Friday, October 10, 2014

Building Boost Libraries quickly

Building Boost

Setting up your development environment

Linux:

1. Fedora/Centos:
You will need:
a. gcc-c++
b. libstdc++
c. libstdc++-devel
Do a yum install or find the rpms on the DVD / net.

2. If you're on *Ubuntu, do a sudo apt-get install of:
a. g++
b. libstdc++-dev
c. libstdc++
Version should be at least 4.8.x - or you'll miss out on the C++11 fun.

3. If you're on Ubuntu and want to try clang, sudo apt-get install the following:
a. clang
b. llvm
c. libc++-dev
Version should be preferably 3.4.

Windows:
If you're on Visual Studio, try to get Visual Studio 2012 or 2013 (Express Edition is free, I have the DVD image for 2013).

Building Boost
Download the boost source archive from boost.org (current version 1.56) and extract it in a directory. Call it <boostsrc>.


Linux:
$ cd <boostsrc>

$ sudo mkdir /opt/boost
$ chown <builduser>:<builduser> /opt/boost
$ ./bootstrap.sh
$ ./b2 install --build-dir=<buildarea> --prefix=/opt/boost --layout=tagged variant=debug,release link=shared runtime-link=shared threading=multi cxxflags="-std=c++11"

<builduser> is the user id of the logged on user.
<buildarea> is the directory where intermediate build products would be generated.

/opt/boost is where the end products would be installed.

Windows:

$ cd <boostsrc>

For 32-bit:
$ "C:\Program Files\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
or
$ "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86 


$ b2 install --libdir=<installdir>\libs --includedir=<installdir>\include --build-dir=<buildarea> --layout=tagged variant=debug,release threading=multi link=shared runtime-link=shared

For 64-bit:
$ "C:\Program Files\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
$ "C:\Program Files\Microsoft Visual Studio 12.0 (x86)\VC\vcvarsall.bat" x86_amd64
$ b2 install --libdir=<installdir>\libs --includedir=<installdir>\include --build-dir=<buildarea> --layout=tagged variant=debug,release threading=multi link=shared runtime-link=shared --address-model=64

<buildarea> is the directory where intermediate build products would be generated.
<installdir> is where you choose to install the products of the build.

Read more!

Wednesday, September 10, 2014

Uses of private inheritance

Found a really cool use of private inheritance in C++ in this answer on stackoverflow: http://stackoverflow.com/a/676725/422131.

More details to follow.

Read more!

Saturday, August 23, 2014

7 useful features in C++14

C++14 is an enhancement over C++11. Here are a few features that are immediately useful:
  1. std::make_unique - a factory function for unique_ptr (which should be the most popular smart pointer) akin to std::make_shared for std::shared_ptr (which shouldn't be the most popular smart pointer).
    #include <memory>
    
    class Foo {
    public:
      Foo(int n) { ... };
      ...
    };
    
    auto fooPtr = std::make_unique<Foo>(10);
    

  2. std::cbegin and std::cend, applied to STL containers give you const_iterators.

  3. std::shared_timed_mutex, a la boost::shared_mutex - a very important addition if you use a fair bit of synchronization. This provides the multiple-reader single-writer (MRSW) type of abstractions.

  4. Getting elements from a tuple by type (if there is a unique element of that type in the tuple).
    std::tuple<int, double, std::string> threeElems = std::make_tuple(1, 2.0, "Foo");
    auto strFoo = std::get<std::string>(threeElems);

    This works, but would have failed had there been two elements of type std::string in the tuple.

  5. Note  how we had to write the type of threeElems in the last example. If we  had used auto instead, its type would be deduced as std::tuple <int, char const*, double> because std::make_shared deduces the type of the  returned tuple using the types of the passed arguments. If you wanted  to use a string literal whose type would be deduced as std::string, you  must use an s suffix like this:
    auto threeElems = std::make_tuple(1, 2.0, "Foo"s);
    auto strFoo = std::get<std::string>(threeElems);
  6. Generic lambdas - essentially lambdas with a very succinct syntax that can be reused for multiple type. Takes a lot of crud away from writing lambdas.
    std::vector<foo> vec;
    std::for_each(vec.begin(), vec.end(), [](auto& elem) { std::cout << elem << '\n'; });

    The  key is the use of the auto keyword for the parameter types. You could  use multiple parameters, all declared auto, whose types are  independently deduced. How does this really help? First, you don't have to write:
    [](Foo& elem) { std::cout << elem << '\n'; }
    
    Also, you could cache a lambda in a generic context with minimal syntactic noise and reuse it for multiple types. Consider this:
    auto elemPrint = [](const auto& elem) { std::cout << elem << '\n'; };
    std::for_each(vecOfInts.begin(), vecOfInts.end(), elemPrint);
    std::for_each(vecOfStrs.begin(), vecOfStrs.end(), elemPrint);
    
    where vecOfInts, vecOfStrs, etc. all contain elements of different, unrelated type.

  7. Being  able to write function with an auto return type, without any trailing  decltype to compute the type. In C++11, you would write something like:
    auto foo(int x, double y) -> decltype(x + y)
    {
       return x + y;
    }
    You can now simply write:
    auto foo(int x, double y)
    {
       return x + y;
    }

    There are several more changes but these stand out in terms of immediate usefulness.

Read more!