Boost logo

Boost :

From: Oleg Abrosimov (olegabr_at_[hidden])
Date: 2003-06-07 08:07:15


Hi all

I found that boost has very powerful configuration system
(boost/config.hpp and around...)
but why use macros?
there is another solution described here, let discuss it...
may be there are some troubles, invisible for me, that prevent from using
this technique
in libraries like boost?

/** may be replacement for BOOST_XXXXX macros in config.hpp :)
* pros:
* minimum use of macros
* more clean c++ code ( no #ifdef/#endif in code)
* more maintainable system dependent code
* cons:
* probably problems with a partial specialization
*/
namespace config
{

/**
* in a file systemXXX.h included in boost/config.hpp
* same struct for all supported systems in a separate files
*/
struct systemXXX_tag {};
struct system_traits
{
  typedef systemXXX_tag system_tag;
  static const bool flag1 = true;
  static const int int1 = 10;
  typedef char char_type;
};

/**
* in a file compilerXXX.h included in boost/config.hpp
* same struct for all supported compilers in a separate files
*/
struct compilerXXX_tag{};
struct compiler_traits
{
  typedef compilerXXX_tag compiler_tag;
  static const bool flag1 = true;
  static const int int1 = 10;
  typedef char char_type;
};

/**
* in file std_libXXX.h included in boost/config.hpp
* same struct for all supported std libraries in a separate files
*/
struct std_libXXX_tag{};
struct std_lib_traits
{
  typedef std_libXXX_tag std_lib_tag;
  static const bool flag1 = true;
  static const int int1 = 10;
  typedef char char_type;
 };

/**
* e.t.c. for all entities that must be wrapped
*/

} //namespace config

//in some library implementation file...
/**
* using in function scope
*/
void foo()
{
  foo_impl<system_traits::system_tag, std_lib_traits::int1>();
}

template <typename System, int int1> void foo_impl()
{
  //implementation for default system and int1
}

/**
* forward declaration
* symbol systemXXX_tag must be defined
*/
struct systemXXX_tag;

template <> void foo_impl<systemXXX_tag, 10>()
{
  //implementation for systemXXX and std_lib_traits::int1 == 10;
}

/**
* using in a class scope
*/
class Foo : private Foo_impl<compiler_traits::compiler_tag>
{
  typedef Foo_impl<compiler_traits::compiler_tag> base_type;
public :
  void method() { base_type::method(); }
};

template<typename Compiler> class Foo_impl
{
  /**
        * implementation details
        */
  int a,b,c;
public :
  void method()
  {
          // default implementation
  }
};

/**
* forward declaration
* symbol systemXXX_tag must be defined
*/
struct compilerXXX;

/**
* there may be a problem with a compiling :)
* if you have more than one template parameter here and
* want to use partial specialization, but
* compiler doesn't support it
* the solution:
* divide your Foo_impl<compilerXXX, platformXXX> class on
* Foo_compiler_impl<compilerXXX> and
* Foo_platform_impl<platformXXX>
* Same technique may be usefull for functions
*/
template<> class Foo_impl<compilerXXX>
{
  /**
        * implementation details
        */
  long a,b,c;
public :
  void method()
  {
          // implementation for compilerXXX
  }
};


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk