Showing posts with label cpp. Show all posts
Showing posts with label cpp. Show all posts

Thursday, 14 May 2015

Convert an enum class to its underlying_type

Generic helper function which takes any enum value and returns that value cast to its integral representation.

template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type 
{
   return static_cast<typename std::underlying_type<E>::type>(e);
}

Since it is constexpr it can be used as follows:

std::array<int, to_integral(my_fields::field)> b;

http://stackoverflow.com/questions/14589417/can-an-enum-class-be-converted-to-the-underlying-type

Tuesday, 10 March 2015

C++11 - Unevaluated operands

Operands of sizeof, typeid, decltype and noexcept are never evaluated

We therefore only need a declaration, not the definition, to use a function or object's name in these contexts

std::declval<T>()  returns T&&
std::declval<T&>() returns T&

decltype( foo(std::declval<T>()) ) returns foo's return type when foo is called with T&&

declval allows us to provide a declaration without having to evaluate the expression (ie: in an unevaluated context) - useful for SFINAE etc

Example: testing for copy-assignability

template<class T>
class is_copy_assignable
{
    template<class U, class=decltype(declval<U&>()=declval<const U&>())>
    static true_type try_assignment(U&&);

    template<class U>
    static false_type try_assignment(...); // catch-all fallback

public:
    using type = decltype(try_assignment(declval<T>()));
};

How this works:

try_assignment(...) will match anything, but is also always the worst match, so if the other try_assignment can match, it will.

type will be the return type of try_assignment, which will either be true_type or false_type

the true_type overload will only work if the expression U& = const U& is valid - ie: if it is copy assignable

We use a second template parameter to allow SFINAE to kick in. It is unnamed because we only use it for SFINAE.

Example: testing for copy-assignability, and requiring an lvalue reference return type

The above example doesn't force a requirement on the copy assignment returning an lvalue reference.

If we assign an alias template to the returned type:

template<class T>
using copy_assignment_t = decltype(declval<T&>() = declval<const T&>());

We can then check whether that is a T& in a SFINAE specialisation

template<class T, class=void>
struct is_copy_assignable 
    : std::false_type {};

template<class T>
struct is_copy_assignable<T, void_t<copy_assignment_t<T>>>
    : std::is_same<copy_assignment_t<T>,T&> {};

Thursday, 23 October 2014

C++ Correct multi threaded singleton initialisation

Correct double-checked locking pattern

1. Pointer must be atomic
2. Check, lock, check, construct

std::atomic<Foo*> foo { nullptr };

Foo* instance()
{
    Foo* f = foo; // single load of foo
    if (!f)
    {
        std::lock_guard<std::mutex> l(foo_lock);
        if (!foo)
        {
            foo = f = new Foo(); // assign both foo and f
        }
    }
    return f;
}

Even better, use std::unique_ptr and std::once to get automatic cleanup and less scaffolding

class Foo
{
public:
    static Foo& instance()
    {
        std::call_once(_create, [=]{
            _instance = std::make_unique<Foo>();
        });
        return *_instance;
    }

private:
    static std::unique_ptr<Foo> _instance;
    static std::once_flag       _create;
};

Or just use a function local static

Foo& Foo::instance()
{
    static Foo foo;
    return foo;
}

C++ decltype and auto type deduction

auto type deduction strips const, volatile and ref

const int& bar = foo;
auto baz = bar; // strips const and ref - therefore type of baz is int

decltype type deduction doesn't strip const, volatile and ref

// decltype of a name

const int& bar = foo;
decltype(bar) // does not strip const and ref - therefore type is const int&

// decltype of an expression
decltype(lvalue expression) always returns an lvalue reference

int arr[5];
arr[0] = 5;
decltype(arr[0]) // lvalue reference, therefore type is int&



C++ type information at run time

std::type_info::name and typeid(T).name() will give incorrect results, as required by the standard

use Boost.TypeIndex

#include <boost/type_index.hpp>

boost::type_index::type_id_with_cvr<T>().pretty_name();
boost::type_index::type_id_with_cvr<decltype(t)>().pretty_name();

C++14 mutable lambda and by-value and by-value init capture

by-value capture vs by-value init capture

by-value capture: type of `i` is `const int`
{
const int i = 0;
auto lambda = [i]() { };
}

by-value init capture: type of `i` is `int`
{
const int i = 0;
auto lambda = [i=i]() { }; 
}

lambda function call operator is const

error: by-value capture: type of `i` is `int`, but default lambda operator() is const member function
{
int i = 0;
auto lambda = [i]() { i = 1; }; 
}

error: by-value init capture: type of `i` is `int`, but default lambda operator() is const member function
{
const int i = 0;
auto lambda = [i=i]() { i = 1; }; 
}

making lambda function call operator mutable

error: by-value capture: type of `i` is `const int`, can't assign, even though lambda operator() is mutable member function
{
const int i = 0;
auto lambda = [i]() mutable { i = 1; };  
}

by-value capture: type of `i` is `int`, and lambda operator() is mutable member function
{
int i = 0;
auto lambda = [i]() mutable { i = 1; };  
}

by-value init capture: type of `i` is `int`, and lambda operator() is mutable member function
{
const int i = 0;
auto lambda = [i=i]() mutable { i = 1; }; 
}

Sunday, 29 June 2014

bjam / boost.build

Boost.Build
Common signature:

rule rule-name
    (
        target-name :
        sources + :
        requirements * :
        default-build * :
        usage-requirements *
    )

target-name is the name used to request the target
sources is the list of source files or other targets
requirements is the list of properties that must always be present when building this target
default-build is the list of properties that will be used unless some other value is already specified (eg: on cmd line or propagation from a dependent target)
usage-requirements is the properties that will be propagated to all targets that use this one

Helper commands:
glob - takes a list shell pattern and returns the list of files in the project's source directory that match the pattern. optional second argument is a list of exclude patterns
lib tools : [ glob *.cpp : exclude.cpp ] ;

glob-tree - recursive glob
lib tools : [ glob-tree *.cpp : .svn ] ;

constant - project wide constant
constant VERSION : 1.34.0 ;

Project:

project project-name
    : requirements <feature>value <feature>value
    ;

Programs:

exe app-name
    : app.cpp some_library.lib ../project//library
    : <threading>multi
    ;

sources is one cpp file (app.cpp), a library in the same directory (some_library.lib) and a Jamfile target (library) specified in the Jamfile found in the path ../project
requirements is that threading is multi

Libraries:
Library targets can represent:

Libraries that should be built from source


lib lib-name
    : lib.cpp
    ;

sources is one cpp file (lib.cpp)

Prebuilt libraries which already exist on the system
Such libraries can be searched for by the tools using them (typically with the linker's -l option), or their paths can be known in advance by the build system.

lib z
    :
    : <name>z <search>../3rd/libz
    ;

lib compress
    :
    : <file>/opt/libs/libcompress.a
    ;

<name> specifies the name of the library without the standard prefixes and suffixes.
In the above example, z could refer to z.so, libz.a, z.lib etc
<search> specifies paths in which to search for the library (in addition to the default compiler paths)
<search> can be specified multiple times, or omitted (meaning only the default compiler paths will be searched)
Note that <search> paths are added to the linker search path (-L) for all libraries being linked in the target, which can potentially lead to libraries from another path being picked up first

Convenience helper syntax for prebuilt libraries

lib z ;
lib gui db aux ;

is the same as

lib z : : <name>z ;
lib gui : : <name>gui ;
lib db : : <name>db ;
lib aux : : <name>aux ;

Prebuilt libraries for different build variants

lib foo
    :
    : <file>libfoo_release.a <variant>release
    ;

lib foo
    :
    : <file>libfoo_debug.a <variant>debug

    ;

Referencing other libraries
When a library references another library, that library should be listed in its list of sources.
Specify library dependencies even for searched and prebuilt libraries

lib z ;
lib png : z : <name>png ;

How Boost.Build includes library dependencies
When a library has a shared library as a source, or a static library has another static library as a source, then an target linking to the first library will also automatically link to the source library

However, when a shared library has a static library as a source, then the shared library will be built such that it completely includes the static library (--whole-archive)
If you don't want this behaviour, you need to use the following:

lib a : a.cpp : <use>b : : <library>b ;

This says that library uses library b, and causes executables that link to a to also link to b, instead of a referring to b

Automatically add a library's header location to any upstream target's include path
When a library's interface is in a header file, you can set usage-requirements for the library to include the path where the header file is, so that any target using the library target will automatically get the path to its header added to its include search path

lib foo : foo.cpp : : : <include>. ;

Control library linking order
If library a "uses" library b, then library a will appear before library b.
Library a is considered to use library b is b is present either in library a's sources or its usage is listed in its requirements
The <use> feature can also be used to explicitly express a relationship.

lib z ;
lib png : : <use>z ;
exe viewer : viewer png z ;

z will be linked before png

Special helper for zlib.
zlib can be configured either to use precompiled binaries or to build the library from source.

Find zlib in the default system location
using zlib ;
Build zlib from source
using zlib : 1.2.7 : <source>/home/steven/zlib-1.2.7 ;
Find zlib in /usr/local
using zlib : 1.2.7 : <include>/usr/local/include <search>/usr/local/lib ;
Build zlib from source for msvc and find prebuilt binaries for gcc.
using zlib : 1.2.7 : <source>C:/Devel/src/zlib-1.2.7 : <toolset>msvc ;
using zlib : 1.2.7 : : <toolset>gcc ;

Builtin features:
variant - build variant. Default configuration values: debug, release, profile.
link - library linking. values: shared, static
runtime-link - binary linking. values: shared, static
threading - link additional threading libraries. values: single, multi
source - useful for adding the same source to all targets in the project (put <source> in requirements), or to conditionally include a source
library - useful for linking to the same libraries for all targets in the project
dependency - introduces a dependency on the target named by the value. If the declared target is built, the dependent target will be too
implicit-dependency - indicates the target named by the value may produce files which the declared target uses.
use - introduces a dependency on the target named by the value, and adds its usage requirements to the build properties of the target being declared. The dependency is not used in any other way.
dll-path - add a shared library search path.
hardcode-dll-path - hardcode the dll-path entries. Values: true, false.
cflags, cxxflags, linkflags - passed on to the corresponding tools.
include - add an include search path.
define - define a preprocessor symbol. A value can be specified: <define>symbol=value
warnings - control the warning level of the compiler. Values: off, on, all.
warnings-as-errors - turn on to have builds fail when a warning is emitted.
build - skips building the target. Useful to conditionally set the value. Values: no.
tag - customize the name of generated files. Value: @rulename, where rulename is the name of a rule with the signature: rule tag ( name : type ? : property-set ). The rule will be called for each target with the default name of the target, the type of the target, and property set. Return an empty string to use the default target name, or a non empty string to be used for the name of the target. Useful for encoding library version nos etc.
debug-symbols - Include debug symbols in the object files etc. Values: on, off.

Objects:
Change behaviour for only a single object file

obj foo : foo.cpp : <optimizarion>off ;
exe bar : bar.cpp foo ;

foo will be built with the special flags, and then van be pulled into other targets

Alias:
Alternative name for a group of targets

alias core : foo bar baz ;

Using core in the source list of any other target or on the command line will translate to the aliased group of targets

Change build properties

alias my_bar : ../foo//bar : <link>static ;

my_bar now refers to the bar target in the foo Jamfile, but has the requirement that it be linked statically

Specify a header only library

alias hdr_only_lib : : : : <include>/path/to/headers ;

Using hdr_only_lib will just add an include path to any targets

Propagation of usage-requirements
When an alias has sources, the usage-requirements of those sources are propagated as well.

lib lib1 : lib1src.cpp : : : <include>/path/to/lib1.hpp ;
lib lib2 : lib2src.cpp : : : <include>/path/to/lib2.hpp ;
alias static_libs : lib1 lib2 : <link>static ;
exe main : main.cpp static_libs ;

Compile main with lib1 and lib2 as static libraries, and their paths are added to the include search path

Installing:
Installing a built target to a relative path

install dist : foo bar ;

foo and bar will be moved to the dist folder, relative to the Jamfile's directory

Installing a built target to specific location

install dist : foo bar : <location>/install/path/location

foo and bar will be moved to /install/path/location

Installing a built target to a path based on a conditional expression
(see conditional expressions below)

install dist 
    : foo bar 
    : <variant>release:<location>dist/release
      <variant>debug:<location>dist/debug ;

foo and bar will be installed to relative path dist/<build-variant>

Installing a built target to a path based on an environment variable
(see accessing environment variables below)

install dist : foo bar : <location>$(DIST) ;

Automatically install all dependencies

install dist 
    : foo
    : <install-dependencies>on
      <install-type>EXE
      <install-type>LIB
    ;

will find all targets foo depends on, and install those which are either executables or libraries.

Preserve directory hierarchy

install headers 
    : a/b/c.h
    : <location>/tmp
      <install-source-root>a
    ;

/tmp/b/c.h will be installed

Install into several directories
use an alias rule to install to several directories

alias install : install-bin install-lib ;
install install-bin : apps : <location>/usr/bin ;
install install-lib : libs : <location>/usr/lib ;

set the RPATH

install installed : application : <dll-path>/usr/lib/snake
                                  <location>/usr/bin ;

will allow the application to find libraries placed in the /usr/lib/snake directory.

Testing:
unit-testing

unit-test foo_test : test.cpp foo ;

behaves just like exe rule, but the test is automatically run after building

testing through another application

unit-test foo_test : test.cpp foo : <testing.launcher>valgrind ;

runs the test through the launcher, eg: valgrind build/path/foo_test

Environment variables:
local foo = [ SHELL "bar" ] ;

Executing external programs:
import os ;
local SOME_PATH = [ os.environ SOME_PATH ] ;
exe foo : foo.cpp : <include>$(SOME_PATH) ;

Conditional expressions:
syntax

property ( "," property ) * ":" property

multiple properties can be combined

exe hello : hello.cpp : <os>NT,<toolset>gcc:<link>static ;

will link hello statically only when compiling with gcc on NT

Command reference:
http://www.boost.org/doc/libs/1_55_0/doc/html/bbv2/reference.html





Thursday, 19 June 2014

Eclipse configuration

Install from eclipse site, not apt-get:

http://www.eclipse.org/downloads/

I decompressed it into /opt/eclipse, and installed a symlink in /usr/bin

$ sudo ln -s /opt/eclipse/eclipse /usr/bin

Increase heap memory available to eclipse (prevents crashing):

$ vim /opt/eclipse/eclipse.ini

-vmargs
-Dosgi.requiredJavaVersion=1.6
-XX:MaxPermSize=1G
-Xms1G
-Xmx2G

Add support for C++11 features for the code inspection

Window -> Preferences -> C/C++ -> Build -> Settings -> Discovery (tab) -> CDT GCC Built-in Compiler Settings. There is "Command to get compiler specs", add "-std=c++11" in there.

Syntax Highlighting theme:

Add the eclipse-color-theme repo to Eclipse marketplace

Help -> Install New Software -> Add -> Location: http://eclipse-color-theme.github.com/update

Select color theme:

Window -> Preferences -> General -> Appereance -> Color Theme : select Monkai or Obsidian or RecognEyes

Editor line highlight colors, etc:

Window -> Preferences -> General -> Editors -> Text Editors

Annotations:

Window -> Preferences -> General -> Editors -> Text Editors -> Annotations

C/C++ Indexer Markers -> Uncheck all
C/C++ Occurrences -> Uncheck Text as Squiggly Line
Codan Errors -> Uncheck all
Codan Warnings -> Uncheck all

Change default Build Action:

Window -> Preferences -> General -> Keys

Filter on "Build"

Remove Ctrl-B from Build All, and add it to Build Project

C++ build console:

Window -> Preferences -> C++ -> Build -> Console

Increase the number of lines
Set colors

Source hover popup:

Window -> Preferences -> C++ -> Editor

Source Hover Background

Automatically close:

Window -> Preferences -> C++ -> Editor -> Typing

Uncheck all auto-close

Editor mark occurrences:

Window -> Preferences -> C++ -> Editor -> Mark Occurrences

Uncheck "Keep marks when the selection changes"

Now restart eclipse to make sure your settings are saved.

Change scalability settings

Window -> Preferences -> C++ -> Editor -> Scalability

Increase number of lines to something larger

Unused:

Color theme:

http://marketplace.eclipse.org/content/eclipse-moonrise-ui-theme

Window -> Preferences -> General -> Appearance : select Dark or MoonRise

Remote System Explorer:

Help -> Install New Software

Search for Remote, I

New connection -> SSH Only

Connect

Sftp files -> navigate to src directory -> Rt click -> Create Remote Project

Project indexer search paths 

Project -> Properties -> C++ General -> Paths & Symbols

Includes
Library Paths

eg:

Includes:
    ${QTDIR}/include
    ${QTDIR}/include/QtCore
    ${QTDIR}/include/QtWidgets
    ${QTDIR}/include/QtGui

Library paths
    ${QTDIR}/include
    ${QTDIR}/include/QtCore
    ${QTDIR}/include/QtWidgets
    ${QTDIR}/include/QtGui

Thursday, 1 May 2014

Solving SFINAE issues when you have overlapping conditions

Sometimes we have function templates which we want to use SFINAE on, but some of them have overlapping conditions, creating ambiguity

template<unsigned N, enable_if_t<is_multiple_of<N, 3>>...>
void print_fizzbuzz(){ std::cout << "fizz\n"; }

template<unsigned N, enable_if_t<is_multiple_of<N, 5>>...>
void print_fizzbuzz(){ std::cout << "buzz\n"; }

template<unsigned N, enable_if_t<is_multiple_of<N, 15>>...> // this is ambiguous
void print_fizzbuzz(){ std::cout << "fizzbuzz\n"; }

By using derived-to-base conversions we can create a total ordering for selecting SFINAE overloads.

That is, we resolve ambiguity by using the following inheritance hierarchy:

template<unsigned I> struct choice : choice<I+1>{};

choice<0> has a higher ordering than choice<1>, and we can therefore use choice<0> as a function parameter to make is_multiple_of<N, 15> a better overload, thereby resolving the ambiguity.

The complete fizzbuzz example:

#include <type_traits>
#include <iostream>

template<class C, class T = int>
using enable_if_t = typename std::enable_if<C::value, T>::type;

template<int N, int M>
struct is_multiple_of : std::integral_constant<bool, N % M == 0>{};

//-------------------------------

template<unsigned I> struct choice : choice<I+1>{};
template<> struct choice<10>{}; // suitably high terminating condition

struct otherwise{ otherwise(...){} };

struct select_overload : choice<0>{};

//-------------------------------

template<unsigned N, enable_if_t< is_multiple_of<N, 15> >...>
void print_fizzbuzz(choice<0>) { std::cout << "fizzbuzz\n"; }

template<unsigned N, enable_if_t< is_multiple_of<N, 3> >...>
void print_fizzbuzz(choice<1>) { std::cout << "fizz\n"; }

template<unsigned N, enable_if_t< is_multiple_of<N, 5> >...>
void print_fizzbuzz(choice<2>) { std::cout << "buzz\n"; }

template<unsigned N>
void print_fizzbuzz(otherwise){ std::cout << N << "\n"; }

template<unsigned N = 1>
void do_fizzbuzz()
{
    print_fizzbuzz<N>(select_overload{});
    do_fizzbuzz<N+1>();
}

template<>
void do_fizzbuzz<50>()
{
    print_fizzbuzz<50>(select_overload{});
}

//-------------------------------

int main()
{
    do_fizzbuzz();
}

This excellent technique by Xeo, as described here

Using function template default parameters to elegantly create SFINAE overloads

Having read Remastered enable_if, some implementation was left as an exercise for the reader.

The article explains how to make use of function template default parameters to elegantly create SFINAE overloads.

Below is my implementation.

#include <iostream>
#include <type_traits>

// true iff all conditions ::values are true
template <typename Head, typename... Tail>
struct all
{
    static constexpr bool value = Head::value && all<Tail...>::value;
};
template <typename Head>
struct all<Head>
{
    static constexpr bool value = Head::value;
};
//---------------------------------

// scoped enum to allow for differentiation between enable/disable
namespace detail { enum class enabler {}; }

template <typename... Condition>
using enable_if_t = typename std::enable_if<all<Condition...>::value, detail::enabler>::type;

template <typename... Condition>
using disable_if_t = typename std::enable_if<!all<Condition...>::value>::type;

//---------------------------------

// example function showing SFINAE overloads
template <typename T,
          enable_if_t< std::is_arithmetic<T>
                     , std::is_integral<T>
                     >...>
T twice(T t)
{
    return 2*t;
}
template <typename T,
          disable_if_t< std::is_arithmetic<T>
                      , std::is_integral<T>
                      >...>
T twice(T t)
{
    return t + t;
}
//---------------------------------

int main()
{
    std::cout << twice(5) << std::endl;
    std::cout << twice(std::string("Hello world")) << std::endl;
    return 0;
}

Read more here

Tuesday, 29 April 2014

Exiting recursive function templates without using helper class templates and partial specialisation

Contrived examples follow, but they serve to illustrate partial specialisation of class templates vs exiting recursive function templates using a branch.

The old way: use a helper class template, partially specialise it with the recursion exit case, and call a static function on this class template from a function template:

#include <iostream>

// helper class template
template<typename T, unsigned idx>
struct foo_impl
{
    static void fn(T t)
    {
        std::cout << t << " " << idx << std::endl;
        foo_impl<T, idx - 1>::fn(t); // recursively call fn
    }
};

// partial specialisation of helper class template for exit case
template<typename T>
struct foo_impl<T, 0>
{
    static void fn(T) {} // do nothing exit case
};

// function template which uses helper class templates
template<unsigned idx, typename T>
void foo(T t)
{
    foo_impl<T, idx>::fn(t);
}

int main()
{
    foo<5>("Hello world");
    return 0;
}

The new way: have the special case branch in the function template itself, and recursively call the function template from itself.

To prevent the compiler from barfing when instantiating the recursive path, the trick is to recursively call the function template with the same parameters for the special case. Even though this code path will never actually execute, it is needed so the compiler can parse the template.

#include <iostream>

template<unsigned idx, typename T>
void foo(T t)
{
    if (idx == 0) // special exit case
        return;
    std::cout << t << " " << idx << std::endl;

    // recursively call the function
    foo<idx - (idx ? 1 : 0)>(t); // note recursion returns itself in special exit case (code path will actually never be reached)
}

int main()
{
    foo<5>("Hello world");
    return 0;
}


Wednesday, 23 October 2013

atomics & fences

Acquire
    cannot move anything up beyond an acquire

Release
    cannot move anything down beyond a release

Note
    acquire/release cannot be reordered with respect to each other
 
What does this mean?

instructions can be reordered from before an acquire to after an acquire
instructions can be reordered from after a release to before a release
acquire cannot be reordered before or after a release
release cannot be reordered before or after an acquire

std::atomic
    read = load_acquire --> read the value == acquire the value
    write = store_release --> write the value == release the value

Sequential Consistency
Transitivity / Causality
Total Store Order


Sunday, 18 August 2013

Generalized function evaluation

#include <type_traits>
#include <utility>

// functions, functors, lambdas, etc.
template<
    class F, class... Args,
    class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type,
    class = typename std::enable_if<!std::is_member_object_pointer<F>::value>::type
    >
auto eval(F&& f, Args&&... args) -> decltype(f(std::forward<Args>(args)...))
{
    return f(std::forward<Args>(args)...);
}

// const member function
template<class R, class C, class P, class... Args>
auto eval(R(C::*f)() const, P&& p, Args&&... args) -> R
{
    return (*p.*f)(std::forward<Args>(args)...);
}

template<class R, class C, class... Args>
auto eval(R(C::*f)() const, C& c, Args&&... args) -> R
{
    return (c.*f)(std::forward<Args>(args)...);
}

// non-const member function
template<class R, class C, class P, class... Args>
auto eval(R(C::*f)(), P&& p, Args&&... args) -> R
{
    return (*p.*f)(std::forward<Args>(args)...);
}

// member object
template<class R, class C>
auto eval(R(C::*m), const C& c) -> const R&
{
    return c.*m;
}

template<class R, class C>
auto eval(R(C::*m), C& c) -> R&
{
    return c.*m;
}

Taken from here: http://functionalcpp.wordpress.com/2013/08/03/generalized-function-evaluation/

Tuesday, 5 March 2013

SFINAE decltype comma operator trick


Note the decltype statement below contains 2 elements: reserve and bool: decltype(t.reserve(0), bool())

This is a trick using SFINAE and the comma operator: SFINAE will cull the function if 'reserve' doesn't exist and the comma operator will mean the result type of the decltype statement will be a bool.

This means we can easily implement an 'enable_if'esque statement to check for the existence of a member function called 'reserve'

// Culled by SFINAE if reserve does not exist or is not accessible
template <typename T>
constexpr auto has_reserve_method(T& t) -> decltype(t.reserve(0), bool()) { return true; }

// Used as fallback when SFINAE culls the template method
constexpr bool has_reserve_method(...) { return false; }

template <typename T, bool b>
struct Reserver
{
  static void apply(T& t, size_t n) { t.reserve(n); }
};

template <typename T>
struct Reserver <T, false>
{
  static void apply(T& t, size_t n) {}
};

template <typename T>
bool reserve(T& t, size_t n)
{
  Reserver<T, has_reserve_method(t)>::apply(t, n);
  return has_reserve_method(t);
}

(Thanks to Matthieu M for his post on stackoverflow here)

--------------------------

Another implementation which has 2 SFINAE functions to access a member int, items_n or items_c, ultimately falling back to 0 if neither exist

// culled by SFINAE if items_n does not exist
template<typename T>
constexpr auto has_items_n(int) -> decltype(std::declval<T>().items_n, bool())
{
    return true;
}
// catch-all fallback for items with no items_n
template<typename T> constexpr bool has_items_n(...)
{
    return false;
}
//-----------------------------------------------------

template<typename T, bool>
struct GetItemsN
{
    static int value(T& t)
    {
        return t.items_n;
    }
};
template<typename T>
struct GetItemsN<T, false>
{
    static int value(T&)
    {
        return 0;
    }
};
//-----------------------------------------------------

// culled by SFINAE if items_c does not exist
template<typename T>
constexpr auto has_items_c(int) -> decltype(std::declval<T>().items_c, bool())
{
    return true;
}
// catch-all fallback for items with no items_c
template<typename T> constexpr bool has_items_c(...)
{
    return false;
}
//-----------------------------------------------------

template<typename T, bool>
struct GetItemsC
{
    static int value(T& t)
    {
        return t.items_c;
    }
};
template<typename T>
struct GetItemsC<T, false>
{
    static int value(T&)
    {
        return 0;
    }
};
//-----------------------------------------------------

template<typename T>
int get_items(T& t)
{
    if (has_items_n<T>(0))
        return GetItemsN<T, has_items_n<T>(0)>::value(t);
    if (has_items_c<T>(0))
        return GetItemsC<T, has_items_c<T>(0)>::value(t);
    return 0;
}
//-----------------------------------------------------

When you have two candidates function templates, and want to use SFINAE to choose between them, sometimes you may have a parameter for which both overloads will work.

To prevent ambiguity you can favour one overload over the other.

By using implicit type casting we can make one overload a better match, therefore resolving the ambiguity.

#include <iostream>

template<class T>
auto serialize_imp(std::ostream& os, T const& obj, int)
    -> decltype(os << obj, void())
{
    os << obj;
}

template<class T>
auto serialize_imp(std::ostream& os, T const& obj, long)
    -> decltype(obj.stream(os), void())
{
    obj.stream(os);
}

template<class T>
auto serialize(std::ostream& os, T const& obj)
    -> decltype(serialize_imp(os, obj, 0), void())
{
    serialize_imp(os, obj, 0);
}

struct X
{
    void stream(std::ostream&) const
    {
        std::cout << "\nX::stream()\n";
    }
};

int main(){
    serialize(std::cout, 5);
    X x;
    serialize(std::cout, x);
}

Here the ostream operator overload will be chosen when an object with both operator<< and stream() because by passing in 0 for the 3rd parameter of serialize_imp, we choose the overload with the int parameter, as 0 is an int, whereas the long parameter would require an implicit cast.

(Thanks to Xeo for his post on stackoverflow here)

Monday, 4 March 2013

Boost Compute - GPGPU programming

Pre-release version of boost compute by Kyle Lutz

http://kylelutz.github.com/compute/index.html
https://github.com/kylelutz/compute

Sunday, 3 March 2013

C++ implementation of the Disruptor pattern

original: https://github.com/fsaintjacques/disruptor--

fork: https://github.com/jwakely/disruptor--

Thursday, 29 November 2012

Pattern recognition algorithms

Boost based Computer Vision and Pattern Recognition Library implements many useful algorithms such as Principal Component Analysis, Eigen solver, etc.

http://boostcvpr.sourceforge.net/

Sunday, 4 November 2012

gtest - google unit testing framework

Primer

http://code.google.com/p/googletest/wiki/Primer

Simple test case

#include <gtest/gtest.h>

TEST(TestSuite, TestCase1)
{
    ASSERT_TRUE(expr);
}

TEST(TestSuite, TestCase2)
{
    ASSERT_TRUE(expr);
}

Get the main function for free

Link gtest_main.cc and you get RUN_ALL_TESTS free

What to do if a test fails

Abort the test on expression failure:

    ASSERT_TRUE(expr);

Continue the test on expression failure:

    EXPECT_TRUE(expr);

Floating point comparison:

    ASSERT_FLOAT_EQ(val1, val2);
    ASSERT_DOUBLE_EQ(val1, val2);
    ASSERT_NEAR(val1, val2, epsilon);

    EXPECT_FLOAT_EQ(val1, val2);
    EXPECT_DOUBLE_EQ(val1, val2);
    EXPECT_NEAR(val1, val2, epsilon);

Command line options

Repeat tests (useful for finding subtle race conditions)

    --gtest_repeat=1000 

Enter the debugger upon test failure

    --gtest_break_on_failure

Generate an xml report "foobar.xml"

    --gtest_output="xml:foobar"

Only run some tests

    --gtest_filter=TestSuite* // runs all suites matching TestSuite*
    --gtest_filter=TestSuite*-*.*2 // runs all suites matching TestSuite* except cases ending in '2'
    --gtest_filter=Foo*:Bar* // separate different reg-ex's with ':'



Monday, 24 September 2012

Open BEAGLE - open source genetic programming framework

Open BEAGLE is a C++ Evolutionary Computation (EC) framework. It provides an high-level software environment to do any kind of EC, with support for tree-based genetic programming; bit string, integer-valued vector, and real-valued vector genetic algorithms; and evolution strategy

http://code.google.com/p/beagle/