Monday, November 26, 2012

Modules in C++

Modules in C++ is finally looking like it's going to happen. Doug Gregor has published an interesting set of slides, check it out [Modules Slides].

This will be huge! There was one factoid that summed up the whole problem with headers, and if you have ever wondered why C++ compilation is slow, then check out this source size comparison:

#include 

int main() {

  std::cout << “Hello, world!”

            << std::endl;

}

Once header substitution has occurred that nice 81 bytes of source blows into a whopping 1,161,033 bytes of convoluted template mess. What? The compiler has to parse a million characters just to print “Hello, world!” ??? That's crazy.

It's a wonder C++ compilers are as fast as they are. Really.

Tuesday, June 5, 2012

OpenGL and Move Semantics

Every C++ programmer who regularly uses OpenGL quickly yearns to wrap an object-oriented facade over it. OpenGL's API is - how shall we put it - very state driven, unsafe and hard to manage. Adding C++ style automatic resource and object management would clearly be a good thing™.

 Safely in C++ typically means value semantics, that is, objects can by created freely, copied about, placed into containers and clean up automatically on scope exit. Now value semantics heavily implies copy semantics, But what happens when we are dealing with resources that don't like to be copied, and don't like to share? That just about describes every OpenGL resource!
 With c++98 modelling these types is problematic, we can declare the copy constructor and assignment operator private for safety, but now we are stuck with lifetime management and usability issues.

 The options are:

  1.  Give up and manage by pointer. This is the easiest method (at least initially). Safety guarantees are all but gone - we must explicitly clean up resources. Resource ownership issues abound. 
  2. Manage by a non-intrusive smart pointer, such as shared_ptr. This has the advantage of not requiring intrusive code to be written in the resource, and is safe. But, it imposes pointer semantics, implies sharing when in fact only unique access is permitted. 
  3. Manage by an internal ref counting. The object itself manages a ref count, either explicitly (such as COM AddRef) or implicitly by implementing in the copy constructor and assignment operator. This is intrusive, but at least gives the illusion of value semantics. Again, implies sharing.  
  4. Attempting to manage and limit object access solely through the use of a manager class. This is just too painfull.
In C++11 we can actually match the usage pattern of resources more closely to the underlying limitations. A GPU resource does not like to be copied, but it can be moved. It does not like to be shared, so don't share it!
Much has been written on how move semantics improves the performance on large classes like strings and vectors. But move semantics is also useful for safety on small handle classes (such as GPU resources)

 This leads to the following:
  1.  Resources should disable copying by deleting the copy construction and assignment operator.
        void operator=( const T& ) = delete;  
        T( const T& ) = delete; 
  2. A move constructor and move operator= should be written 
  3. The destructor should guard against freeing a moved resource. 
  4. Resources should typically be held by value or by unique_ptr. They should be passed to functions by reference. 
  5. Factories should return by value (if not polymorphic) or by unique_ptr. 
  6. If needed resources can always be moved (std::move) into a unique_ptr or shared_ptr.
        auto share = shared_ptr< T >( new T( std::move( value ) ) ); 
Now we have the best of both worlds, we can create, embed into containers, and can move things around as needed. In an emergency we can even move construct into a shared_ptr. We cannot copy or implicily share, which is exactly the prodding needed to do the right thing™.

Shader class skeleton:
class Shader: public boost::noncopyable {
 friend class ShaderManager;
public:
 Shader( GLuint program )
  : program_( program )
 { }
 ~Shader( ) {
            if ( program_ ) glDeleteProgram( program_ );
        }
 // move constructor
 Shader( Shader&& other )
  : program_( other.program_ )
 { 
  // wipe program_ so the destructor doesn't release it...
  other.program_ = 0; 
 }
 Shader& operator=( Program&& other ) {
     if ( program_ ) glDeleteProgram( program_ );
     program_ = other.program_;
      other.program_ = 0;
     return *this;
        }
private:
        GLuint program_;
};
Consider a scene class which holds some OpenGL shaders, The use of move semantics allows for a very natural usage pattern, safely.
 class Scene {
public:
   Scene( )
       :   explosion( ShaderFactory::Create( "Explosion" ) ) 
       ,   alien( ShaderFactory::Create( "Alien" ) ) 
    { }

   ~Scene( ){ 
     // nothing to do here cleanup is handled!
    }

    void onFrame( ) {
        explosion.bind( );  // yippee! value semantecs
        // stuff....
    }
private:
    Shader explosion;
    Shader alien;
};

Thursday, April 26, 2012

std::tie and Strict Weak Ordering


One of the requirements for placing objects into a std::map or std::set is that the Key type has Strict Weak Ordering, usually via std::less. Writing a suitable comparator for an abritary structure is a pretty trivial excercise. The problem is,  it is also trivially easy to make a mistake.
If the comparator is not Strict Weak, there will be no compiler warning or alarm bells. Worse still, if you are unlucky, there will be no indication at runtime either. Just occasional, seemingly at random, inserting or deleting an item will segfault.
If only we didn't have to write these trivial comparators ourselves!

The C++ Standard Committe has a paper n3326 on compile time reflection that contains a hidden little gem. The tuple helper function std::tie can be used to write a comparator function for you!

A quick reminder, std::tie is a shorthand way of binding seperate elements to a tuple.
tuple< int, int > coords( 1, 2 );
int x;
int y;
tie( x, y ) = coords;

The trick to tie is that it creates a tuple of references to elements - its the reference version of make_tuple. Usefully a tuple defines the full set of comparison operators ==, <, >, >=, <= and !=. The comparison operators are not restricted to the exact same tuple type either, but work with any tuple where each corresponding member is comparable.

It's the ability to tie references into a tuple combined with the tuple comparison operators that allows the shorthand trick. Consider the following struct:

struct Burger {
  int  bacon;
  int  meat; 
  int  green_stuff;
  string name;
};
Thanks to std::tie we can easily write a map friendly operator<:

bool operator<( const Burger& l, const Burger& r ) {
  return tie( l.bacon, l.meat, l.green_stuff, name ) < tie( r.bacon, r.meat, r.green_stuff, r.name );
}


similarly equality:

bool operator==( const Burger& l, const Burger& r ) {
  return tie( l.bacon, l.meat, l.green_stuff, name ) == tie( r.bacon, r.meat, r.green_stuff, r.name );
}

That not only saves a lot of typing but is safer too. Even better, there is no abstraction penalty to pay, a release build  produces identical code to a hand written function.

There is a caveat though, as usual care needs to be taken with floating point types. Unfortunately the ieee standard dictates that floats set to NAN will compare unordered always - even when compared with itself. Because of this float types do not satisfy Strict Weak Ordering when set to NAN, so the above tie trick fails unless you are careful to never place a NAN into a map key.


Friday, April 13, 2012

C++11 string switch

C++11 added a slew of new features - lambda, auto, uniform initilizers, move semantics - the list is large. Near the bottom, almost forgotten, is general const expressions. C++11 adds the new keyword constexpr (n2335), which at first glance seems like just an esoteric tightening of const, but actually is so much more.  C++ has always had the constant expressions, so explicitly labelling something as such would seem to not gain much. But au contraire, constexpr is an incredibly useful addition that will greatly simplify meta programming in C++.

What can you do with constexpr that you can't you do with templates? Turns out, lots:

You can generate a compile time string hash (string hashing). Perform all sorts of compile time string manipulation (constexprstr). Do compile time unit conversion, and generate philosphical debate (turing).

constexpr can also interact with other C++11 features in interesting ways. For example using string hashing and user literals it is possible to do a very good approximation of a string switch statement.

Lets start with a compile time string hasher, like the one found here.

// FNV-1a constants
static constexpr unsigned long long basis = 14695981039346656037ULL;
static constexpr unsigned long long prime = 1099511628211ULL;

// compile-time hash helper function
constexpr unsigned long long hash_one(char c, const char* remain, unsigned long long value)
{
    return c == 0 ? value : hash_one(remain[0], remain + 1, (value ^ c) * prime);
}

// compile-time hash
constexpr unsigned long long hash_(const char* str)
{
    return hash_one(str[0], str + 1, basis);
}

// run-time hash
unsigned long long hash_rt(const char* str) {
    unsigned long long hash = basis;
    while (*str != 0) {
        hash ^= str[0];
        hash *= prime;
        ++str;
    }
    return hash;
}
constexpr long long operator"" _hash( const char* str, size_t n ) {
    return hash_( str );
}

Now we can use the _hash string literal to generate a compile time string hash, which can be used anywhere a constant expression can be, such in in non-type template parameters and switch statements!
template < long long n >
struct some_template {
    static const long long value = n;
};

void print( const char * str ) {
    switch ( hash_( str ) ) {
       case  "hello"_hash: std::cout << "hello string passed\n"; break;
       case  "world"_hash: std::cout << "world string passed\n"; break;
    };
}

int main() {

    long long hash = some_template< "hello"_hash >::value;

    print( "hello" );
    print( "world" );

    return 0;
}

Of course it's not really limited to strings either, the technique can be extended to any type that has a hash and constexpr constructor.

Tuesday, March 27, 2012

Welcome

Ahhh, yet another programming with emphasis on C++ blog. Now that twitter and facebook are taking over the web, I thought it was time to dust off the 'previous big thing' and actually start writing a blog. Maybe I'll start tweeting around 2020. Until then expect the odd rambling post here.