I have three classes which adhere to the same concept class but differ on the underlying data structure used for storage. As an illustration take the three classes given below.
template< typename T >
class A{
std::vector<T> storage;
//etc
};
template<>
class A<bool>{
boost::dynamic_bitset<> storage;
//etc
};
class B{
ComplexUDT storage;
//etc
};
Class A is the generic class that uses a vector. To avoid the use of vector<bool>
a full specialisation of class A is provided that uses the boost::dynamic_bitset<>
as the underlying storage. Finally, Class B uses a user defined data type as storage. The above design leads to a lot of redundancy in code. To remove this redundancy I thought of using boost::mpl
template< typename T >
class vec_impl{
std::vector< T > storage;
//impl of methods
};
class bitset_impl{
boost::dynamic_bitset<> storage;
//impl of methods
};
class udt_impl{
ComplexUDT storage;
//impl of methods
};
template<Derived,Storage>
class main_class_gen{
typedef typename boost::mpl::if_<is_complexudt<Storage>,
udt_impl,
typename boost::mpl::if_< is_bool<Storage>,
bitset_impl,
vec_impl<Storage> >::type >::type type
};
class main_class:
public main_class_gen< main_class<Storage>,Storage >::type{
//impl. of methods
};
As boost::dynamic_bitset does not model a Container the implementation of some of the class methods are different than the vector class. The complexUDT bases class is very different from the two other classes but do have some small code segements common. But the current refactoring approach still results in code redundancy. All the methods mentioned in the concept class have to implemented in the each of the implementations.
So I my question is two fold.
- How can we implement the Builder design pattern using boost::mpl ?
- Would CRTP help in any way in the above example ?