Tuesday, December 6, 2016

Running the Lua (5.2) C API in Ubuntu 14

Took me some time to figure this out trying out this example.

First you need to install Lua:

ubuntu> sudo apt-get install lua5.2
ubuntu> sudo apt-get install liblua5.2-dev

Then compile the source file:

ubuntu> gcc a.c -I/usr/include/lua5.2 -L/usr/lib/x86_64-linux-gnu -llua5.2

I had to make some adjustments in the source file. The adjusted source file is as follows:

Friday, September 2, 2016

Exercise 3-3 Abrahams & Gurtovoy

Turn T into T**** by using twice twice.

Exercise 3-1 of Abrahams & Gurtovoy

Turn vector_c<int,1,2,3> into a type sequence with elements (2,3,4) using transform.

Tuesday, August 30, 2016

Exercise: Use BOOST_STATIC_ASSERT to add error checking to the binary template presented in section 1.4.1 so that binary<N>::value causes a compilation error if N contains digits other than 0 or 1.

Saturday, August 27, 2016

boost::mpl addition of physical quantity

This is a demonstration of addition of physical quantities using dimensional analysis:


boost::mpl equating with dimensions

Equating two physical quantities can only be done if both of them have the same dimensions. For example, a length variable can be equated to another length variable as both of them have the same dimensions (e.g., meters). It is not possible, however, to equate two physical quantities of different dimensions. For example, a mass variable cannot equated to a length variable:

boost::mpl integral constant wrappers

Am trying to follow this tutorial on boost::mpl

First, I tried this integral constant wrapper:

Guess what it prints out when run. It simply prints "5".

Monday, August 8, 2016

Full configuration

In LTE, there's this thing called full configuration. I guess it's usually used in handovers. During a handover, the source eNodeB informs the target eNodeB about the source eNodeB's enabled features. For instance, the source eNodeB may inform the target eNodeB that it was performing 256QAM with the UE.

Sometimes, however, the target eNodeB does not support the features the source eNodeB was using with the UE. For instance, the source eNodeB may have been previously using 256QAM with the UE, but the target eNodeB may not have support for this feature. When this happens, the target eNodeB may issue a full configuration to the UE. It does this by sending an RRC Connection Reconfiguration message to the UE. This message is first sent to the source eNodeB, then passed as is (without modification) to the UE.

The target eNodeB informs the UE that a full configuration is in progress by sending the fullConfig-r9 information element. During full configuration, the target eNodeB has to resend all information related to bearer setup (as if these bearers were being set up from scratch or for the first time).

In the case of DRB bearers, the DRB-ToAddMod message has to have the following elements present during full configuration:
  1. eps-BearerIdentity
  2. pdcp-Config
    1. discardTimer
    2. rlc-AM or rlc-UM (one of them, but not both, has to be present)
  3. rlc-Config
  4. logicalChannelIdentity
  5. logicalChannelConfig

Saturday, July 30, 2016

Inheritance in Lua

Consider this code:

This is the output when run:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/oop$ ./inheritance.lua
Calling constructor for table: 0x2414180
Accessing key = new for table: 0x2412f40; self = table: 0x2414180
Calling constructor for table: 0x2412f40
Accessing key = deposit for table: 0x2411eb0; self = table: 0x2412f40
Accessing key = deposit for table: 0x2412f40; self = table: 0x2414180
Account:deposit(): self = table: 0x2411eb0
Accessing key = balance for table: 0x2411eb0; self = table: 0x2412f40
Accessing key = balance for table: 0x2412f40; self = table: 0x2414180
Accessing key = withdraw for table: 0x2411eb0; self = table: 0x2412f40
SpecialAccount:withdraw(): self = table: 0x2411eb0
Accessing key = getLimit for table: 0x2411eb0; self = table: 0x2412f40
SpecialAccount:getLimit(): self = table: 0x2411eb0
Accessing key = get_balance for table: 0x2411eb0; self = table: 0x2412f40
Accessing key = get_balance for table: 0x2412f40; self = table: 0x2414180
Account:get_balance(): self = table: 0x2411eb0
-100
kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/oop$

Notice how searching for a key is recursive. When a key is not found in s, it is searched in SpecialAccount. When the key is not found in SpecialAccount, it is searched in Account.

Classes in Lua

This is an adaptation of the code found here:

When run, the output looks like this:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/oop$ ./l.lua 
Calling constructor for table: 0x8a2160
Accessing key = deposit for table: 0x8a1df0; self = table: 0x8a2160
Account:deposit(): self = table: 0x8a1df0
Accessing key = get_balance for table: 0x8a1df0; self = table: 0x8a2160
Account:get_balance(): self = table: 0x8a1df0
a's balance: 100
Calling constructor for table: 0x8a2160
Accessing key = deposit for table: 0x89a4a0; self = table: 0x8a2160
Account:deposit(): self = table: 0x89a4a0
Accessing key = balance for table: 0x89a4a0; self = table: 0x8a2160
Account:balance = 0
Accessing key = withdraw for table: 0x89a4a0; self = table: 0x8a2160
Account:withdraw(): self = table: 0x89a4a0
Accessing key = get_balance for table: 0x89a4a0; self = table: 0x8a2160
Account:get_balance(): self = table: 0x89a4a0
b's balance: 60
kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/oop$ 



Thursday, July 21, 2016

Compiling and running Google test and Google mock in Ubuntu

To compile and run Google Test and Google Mock in Ubuntu, you can follow these steps.

First download Google Test from here. Extract the downloaded zip file to a directory of your choice.

After extraction, you will see a folder named googletest-master. Enter this folder.

Inside the googletest-master folder, you will see these two folders: googletest and googlemock.

To compile and test run google test, go to the googletest directory. There you will see a make directory. Go inside the make directory and type 'make'.

Executing the make command will create the executable file, sample1_unittest. You can then run this executable file:

kuyu@castor-ub:~/dkuyu/bin/googletest-master/googletest/make$ pwd; ls
/home/kuyu/dkuyu/bin/googletest-master/googletest/make
Makefile
kuyu@castor-ub:~/dkuyu/bin/googletest-master/googletest/make$ make && ./sample1_unittest
g++ -isystem ../include -g -Wall -Wextra -pthread -c ../samples/sample1.cc
g++ -isystem ../include -g -Wall -Wextra -pthread -c ../samples/sample1_unittest.cc
g++ -isystem ../include -I.. -g -Wall -Wextra -pthread -c \
            ../src/gtest-all.cc
g++ -isystem ../include -I.. -g -Wall -Wextra -pthread -c \
            ../src/gtest_main.cc
ar rv gtest_main.a gtest-all.o gtest_main.o
ar: creating gtest_main.a
a - gtest-all.o
a - gtest_main.o
g++ -isystem ../include -g -Wall -Wextra -pthread -lpthread sample1.o sample1_unittest.o gtest_main.a -o sample1_unittest
Running main() from gtest_main.cc
[==========] Running 6 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 3 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 3 tests from FactorialTest (0 ms total)

[----------] 3 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 3 tests from IsPrimeTest (0 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 2 test cases ran. (0 ms total)
[  PASSED  ] 6 tests.
kuyu@castor-ub:~/dkuyu/bin/googletest-master/googletest/make$ 

You can follow similar steps to compile and test run Google Mock in Ubuntu. From the googletest-master directory, go to the googlemock/make directory. Then type make. The executable created by the make command is named gmock_test.

You can actually study the Makefile file in the googletest/make and googlemock/make directories. There you can edit the GTEST_DIR, USER_DIR, and GMOCK_DIR (for googlemock).

Wednesday, July 20, 2016

Google test

Getting started in Google test is also difficult.

To setup Google test to run in Ubuntu, I followed this site.

CppUMock example

This is an example CppUMock test. It consists of 3 files: test_main.cpp, test.cpp and makefile.

test_main.cpp:

test.cpp:

makefile:

Output:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/cpp/cpputest/ho$ make && ./a.out
g++ -g -I/usr/local/include  -c test_main.cpp
g++ -g -I/usr/local/include  -c test.cpp
g++ -g -o a.out test.o test_main.o -L/usr/local/lib -lCppUTest -lCppUTestExt
testBody: pProtocolFsm=0x189d4c0
ProtocolProcedure: Got 3
ProtocolProcedure: Got 5
ProtocolProcedure: Got 7
.
OK (1 tests, 1 ran, 3 checks, 0 ignored, 0 filtered out, 1 ms)

kuyu@castor-ub:~/dkuyu/Dropbox/practice/cpp/cpputest/ho$ 

Wednesday, July 13, 2016

cpputest

I spent several hours figuring out how to run cpputest in Ubuntu. I searched several websites, but they were not helpful. You can imagine the agony that I went through.

Finally, I came across this stackoverflow question. Thank you, pradeep (the author of the question (and also the answer)).

Well, first you need to install CppUTest in Ubuntu:

% sudo apt-get install cpputest

After that, create the files: test.cpp, test_main.cpp, and makefile

For the makefile file, be sure to use tab indentations and not spaces.

After creating the files:

kuyu@castor-ub:~/dkuyu/practice/cpp/cpputest/hello$ make 
g++ -g -I/usr/local/include  -c test_main.cpp
g++ -g -I/usr/local/include  -c test.cpp
g++ -g -o mytest test.o test_main.o -L/usr/local/lib -lCppUTest -lCppUTestExt
kuyu@castor-ub:~/dkuyu/practice/cpp/cpputest/hello$ ./mytest 

test.cpp:15: error: Failure in TEST(FirstTestGroup, SecondTest)
expected <hello>
but was  <world>
difference starts at position 0 at: <          world     >
                                              ^

.
test.cpp:10: error: Failure in TEST(FirstTestGroup, FirstTest)
Fail me!

.
Errors (2 failures, 2 tests, 2 ran, 1 checks, 0 ignored, 0 filtered out, 1 ms)

kuyu@castor-ub:~/dkuyu/practice/cpp/cpputest/hello$ 

It finally ran.

Saturday, July 9, 2016

Iterator swap for vector proxy class

Here is an example of iterator swapping for the vector<bool> proxy class:

Here is the output:

kuyu@castor-ub:~/dkuyu/practice/cpp/iter_swap_bool$ g++ -Wformat=0 iter_swap_bool.cpp && ./a.out
Before swap
a.bytes=0x7ffdd8f29760 a.pos=3 a.bool=1
b.bytes=0x7ffdd8f29760 b.pos=12 b.bool=0
After 1st swap
a.bytes=0x7ffdd8f29760 a.pos=3 a.bool=0
b.bytes=0x7ffdd8f29760 b.pos=12 b.bool=1
After 2nd swap
a.bytes=0x7ffdd8f29760 a.pos=3 a.bool=1
b.bytes=0x7ffdd8f29760 b.pos=12 b.bool=0
kuyu@castor-ub:~/dkuyu/practice/cpp/iter_swap_bool$

Some questions to consider:
  1. What happens if the function starting at line 25 is deleted?
  2. What happens if the function at line 54 returned proxy& instead of only proxy?

iterator_traits

Been trying to read this book:

Abraham, David; Gurtovoy, Aleksey. 2004. C++ template metaprogramming: Concepts, tools, and techniques from Boost and beyond. Addison Wesley.

Tried to code a little on iterator_traits:

When I run it:

kuyu@castor-ub:~/dkuyu/practice/cpp/iterator_traits$ g++ iterator_traits.cpp && ./a.out 
Before:
a = a
b = b
After:
a = b
b = a
kuyu@castor-ub:~/dkuyu/practice/cpp/iterator_traits$ 

Example boost:fusion

Example of boost::fusion vector. It is like a C++ tuple.

I guess you can guess what the output is:

kuyu@castor-ub:~/dkuyu/practice/cpp/boost/fusion$ g++ -I/home/kuyu/dkuyu/bin/boost_1_60_0 vec.cpp && ./a.out 
howdy
kuyu@castor-ub:~/dkuyu/practice/cpp/boost/fusion$

Tuesday, July 5, 2016

make

I've always been confused about make and makefiles.

One of the simplest tutorials on make I found is this.

Tuesday, June 28, 2016

My first C++14 code

Here is my first C++14 code.

The code uses a function (a lambda function) whose argument is an auto.

To compile and run this code in Linux:

g++-5 -std=c++14 cpp14.cpp && ./a.out

Of course, you need to install g++-5 first in order to use C++14. In Ubuntu:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install g++-5

When Lambda capture by reference goes wrong

Here is a code that demonstrates lambda capture by value vs reference:

Running this code would yield 4.

When line 10 is used instead of line 9, running this code yields 10 instead of 4.

Ideally, 4 should be returned as the remainder of 10 divided by 6. If line 10 is used, however, the lambda function created encloses a reference to the variable x which goes out of scope as soon as the function add_func() completes execution.

After add_func() is called, the lambda function stored inside the vector uses a reference to x which is no longer valid (x only exists while add_func() is being executed). Therefore, the lambda function uses a reference to a variable with undefined value. Calling the lambda function therefore will yield to undefined results.

Monday, June 27, 2016

Factorial via template metaprogramming

Here is an example implementation of factorial via template metaprogramming:

Saturday, June 25, 2016

When auto fails

Got this from the book "Effective modern C++" by Scott Meyers (2014).

The book recommends the use of auto instead of explicit types. He does warn against using auto when proxy classes are involved. One example is std::vector<bool>. Using the operator[] on a std::vector<bool> yields a std::vector<bool>::reference (a proxy class) instead of a simple bool.

Consider this example:

 According to Meyers, std::vector<bool>::reference is a class (a proxy class) that contains a pointer to a word (probably a 32-bit or 64-bit memory location) that contains the boolean value. The class also contains the offset within the word to be able to locate the boolean value.

So in the example, in line 22, b is of type std::vector<bool>::reference which contains a pointer to some memory location. Note, however, that features() returns a temporary std::vector<bool> which goes out of scope as soon as line 22 finishes execution. Thus, after line 22 is executed, the word (memory location) which contains the boolean goes out of scope. The pointer within b then becomes a dangling pointer pointing to who knows what.

When the code is executed:

nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
0/100

If line 23 is executed instead of line 22:

nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
100/100

Meyers calls the style used in line 23 as "the explicitly typed initializer idiom".

std::move example

Here is an example of move semantics:

When line 24 is used:

nonbonding@castor-ub:~/dnonbonding/tmp/rvalue$ g++ -std=c++11 c.cpp && time ./a.out
200000000
200000000

real 0m31.475s
user 0m24.932s
sys 0m4.604s

When line 25 is used instead of line 24:

nonbonding@castor-ub:~/dnonbonding/tmp/rvalue$ g++ -std=c++11 c.cpp && time ./a.out 
200000000
0

real 0m17.334s
user 0m16.708s
sys 0m0.440s

Execution time was reduced by almost a half!

DL 256QAM

In LTE, downlink 256QAM is triggered by a handshake between the UE and the eNodeB. First the UE signifies it is capable of performing 256QAM by sending the RRC information element (IE) dl-256QAM-r12 to the eNodeB. Should the eNodeB choose to perform 256QAM, then it sends the RRC IE altCQI-Table-r12 to the UE.

altCQI-Table-r12 is sent through the RRC message CQI-ReportConfig-r1250 which is a "Need ON" optional message. "Need ON" means that no action should be done by the UE if the UE does not receive the message again, upon say, RRC reconfiguration.

So to trigger 256QAM in the downlink, first, the UE sends dl-256QAM-r12 to the eNB to signify it is capable of 256QAM. Then the eNodeB sends CQI-ReportConfig-r1250 containing altCQI-Table-12 to the UE.

In case of RRC reconfiguration, say during handover, and the eNodeB still desires to continue using 256QAM, then it need not send CQI-ReportConfig-r1250 anymore to the UE because of the "Need ON" condition. Remember "Need ON" means that if the IE is not sent again (during reconfiguration), then the UE should maintain the status quo: if it was previously configured to use 256QAM, then after reconfiguration, it should still use 256QAM.

If the UE was previously configured by the eNodeB to use 256QAM, and after reconfiguration, the eNB does not wish to continue to use 256QAM anymore, then the eNodeB has to send CQI-ReportConfig-r1250 with no altCQI-Table-r12. The eNodeB has to send CQI-ReportConfig-r1250 with altCQI-Table-r12 missing or absent, in order to turn off 256QAM. If it does not send CQI-ReportConfig-r1250, then it means that the eNodeB still wishes to continue using 256QAM (remember "Need ON").

See 3GPP TS36.331 for more details.

boost::any

My first attempt at using boost::any.

Adapted this code from here:

Here's the sample output:

nonbonding@castor-ub:~/dnonbonding/tmp/any$ g++ -std=c++11 -I/home/nonbonding/dnonbonding/bin/boost_1_60_0 c.cpp 
nonbonding@castor-ub:~/dnonbonding/tmp/any$ ./a.out 
#empty == 1
#int == 2
#const char * == 2
#string == 1
1 hello (empty) there world 6 
nonbonding@castor-ub:~/dnonbonding/tmp/any$