Boost logo

Boost Users :

Subject: [Boost-users] [preprocessor] It works, but how can I make it better/more elegant?
From: Geoff Hilton (geoff.hilton_at_[hidden])
Date: 2010-07-28 13:47:56


Yay! I finally got my type map generating code to work! There has got to
be a better way though because it feels really kludgey. Opinions? If you
have a more elegant way of accomplishing the same thing (without
misusing BOOST_PP_APPLY as I think I did, because I only used it to
remove the extra pair of parens surrounding the tuple in
TEST_PP_get_type, something that, oddly, BOOST_PP_TUPLE_REM_CTOR doesn't
succeed at doing (at least not without breaking the current code).

Was I correct in my assumption (which is why I handled it the way I did
in my below code) that basically anytime a a comma appears, the two
surrounding tokens must be treated as a tuple (and thus parenthesized?
This is what I've gathered from the online documentation as well as the
"C++ Template Metaprogramming" book.

The purpose of this code is to create a type map between array types and
corresponding value types of 3rd party classes which don't conform at
all to STL usage practices, that which I'd like to use, so I'm writing
an array wrapper template class with associated iterator template
classes using iterator_facade & the MPL. The map generated by this code
is used to map between array and value types for type selection purposes.

The following (reformatted for readability) code should generate this
(also reformatted) preprocessed output, though I've only tested the real
code and not this that is mostly copy/pasted:

typedef bmpl::map<
   bmpl::pair<SomeIntArray, SomeInt>,
   bmpl::pair<SomeDoubleArray, SomeDouble>,
   bmpl::pair<SomeBoolArray, SomeBool>,
   bmpl::pair<SomeOtherClassArray, SomeOtherClass>
> supported_types_map;

--test.hpp--
(omitting #inclusions)
namespace blah {
namespace bmpl = boost::mpl;

//must match size as below tuples in sequence for readability.
#define TEST_PP_tuple_size 2

//index of array type inside tuple for readability.
#define TEST_PP_array_descriptor 0

//index of value type inside tuple for readability.
#define TEST_PP_value_descriptor 1
//sequence of tuples of supported types
#define TEST_PP_supported_types \
((SomeIntArray, SomeInt)) \
,((SomeDoubleArray, SomeDouble)) \
,((SomBoolArray, SomeBool)) \
,((SomeOtherClassArray, SomeOtherClass))\
/**/

//size of TEST_PP_supported_types (BOOST_PP_SEQ_SIZE doesn't work on it)
#define TEST_PP_types_size 4

#define TEST_PP_get_type(index, type_descriptor) \
   BOOST_PP_TUPLE_ELEM(TEST_PP_types_tuple_size, \
     type_descriptor, \
     TEST_PP_get_tuple(index) \
   ) \
/**/

//gets tuple from TEST_PP_supported_types
#define TEST_PP_get_tuple(index) \
   BOOST_PP_APPLY( \
     BOOST_PP_TUPLE_ELEM( \
       TEST_PP_types_size, index, (TEST_PP_supported_types)\
     ) \
   ) \
/**/

//this returns a tuple containing the first and last part of the mpl::pair
#define TEST_PP_bmpl_pair(index) \
   (bmpl::pair<TEST_PP_get_type(index, TEST_PP_array_descriptor), \
     TEST_PP_get_type(index, TEST_PP_value_descriptor)>) \
/**/

#define TEST_PP_pair_fwder(next_index, index, data) \
   BOOST_PP_TUPLE_REM_CTOR(2,TEST_PP_bmpl_pair(index)) \
/**/

typedef bmpl::map<
   BOOST_PP_ENUM(TEST_PP_types_size, TEST_PP_pair_fwder, ~)
> supported_types_map;
} //namespace blah

Thank you!
Geoff


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net