When dealing with any favor of variant classes, we will always need to pay a penalty of extra space used to somehow keep trace of actual type being currently stored inside. For example, VARIANT struct used in COM, which is basically a big union of different possible types (primitive types or pointers to classes), also contains VARTYPE vt to store the current type.

Our variant uses its extra space in a different way, and we'll see it a minute. First we define an interface for type-specific methods:
<typename TLIST>
class variant {
   struct basic_type_wrapper {
      virtual std::ostream & print(std::ostream &out, const char *buf) const = 0;
      virtual const type_info & getTypeInfo(void) = 0;
      // etc.
   };
}; 


And we define a template for per-type implementations of this interface:
<typename TLIST>
class variant {
   struct basic_type_wrapper { /*...*/ };

   template<typename T>
   struct specific_type_wrapper : public basic_type_wrapper {
      virtual std::ostream & print(std::ostream &out, const char *buf) const {
         return (out << (*getT(buf)));
      }

      virtual const type_info & getTypeInfo(void) {
         return typeid(T);
      }
   };
}; 


All those functions are "static" in a sense that they don't use any members of the class (actually, the class has no members at all), so you can already predict what will the size of those classes be - exactly the size of a single pointer to virtual table. But let's still see how can we ensure that we allocate correct amount of memory.

First, we create a new typelist - a list of specific_type_wrappers for each one of original types. In this task we can rely on "for each" meta-function (described in previous section):
typedef typename apply_for_each<TLIST, specific_type_wrapper>::type wraplist;

Now we can allocate a buffer in same way we did for the "main" object space:
char _buf_wrapper[sizeof(typename largest_type<wraplist>::type)];


BTW, boost's variant keeps an int index of the current type from the typelist.

Last edited Nov 30, 2007 at 11:33 PM by migo, version 1

Comments

No comments yet.