2014-10-20 7 views
5

Wie boost :: preprocessor verwenden, um eine Sequenz von Paaren zu entpacken?Wie boost :: preprocessor verwenden, um eine Sequenz zu entpacken?

Zum Beispiel habe ich eine Sequenz wie unten (durch Komma zwischen spielt keine Rolle)

(int,x)(double,y)(float,z) or 
(int,x),(double,y),(float,z) or 
((int)(x))((double)(y))((float)(z)) 

und will

int,double,float 

und

x,y,z 

Durch die Verwendung von konvertieren macor wie

UNZIP(i, seq) 

wobei i der Index ist.

+0

Sie haben ein Komma zwischen den beiden letzten Elemente und kein Komma zwischen den ersten beiden. Was bevorzugen Sie? Eigentlich sieht es mit den Kommas viel besser aus. – chris

Antwort

7

Unzipping von (int, x, 10)(double, y, 20)(float, z, 30), das heißt Sequenz ohne Komma zwischen den Elementen.

LIVE DEMO

#include <boost/preprocessor/punctuation/comma_if.hpp> 
#include <boost/preprocessor/seq/for_each_i.hpp> 
#include <boost/preprocessor/seq/pop_front.hpp> 
#include <boost/preprocessor/seq/for_each.hpp> 
#include <boost/preprocessor/variadic/elem.hpp> 
#include <boost/preprocessor/cat.hpp> 

// Such technique is used at: 
// http://www.boost.org/doc/libs/1_56_0/boost/fusion/adapted/struct/define_struct.hpp 
#define AUXILIARY_0(...) ((__VA_ARGS__)) AUXILIARY_1 
#define AUXILIARY_1(...) ((__VA_ARGS__)) AUXILIARY_0 
#define AUXILIARY_0_END 
#define AUXILIARY_1_END 

#define REMOVE_PARENTHESES(...) __VA_ARGS__ 

#define COMMA_SEPARATED(r, data, i, elem) \ 
    BOOST_PP_COMMA_IF(i) BOOST_PP_VARIADIC_ELEM(data, REMOVE_PARENTHESES elem) \ 
/**/ 

#define ZIPPED_TO_SEQ(zipped) \ 
    BOOST_PP_SEQ_POP_FRONT(BOOST_PP_CAT(AUXILIARY_0(0)zipped,_END)) \ 
/**/ 

#define FOR_EACH_ZIPPED_I(macro, data, zipped) \ 
    BOOST_PP_SEQ_FOR_EACH_I(macro, data, ZIPPED_TO_SEQ(zipped)) \ 
/**/ 

#define UNZIP(i, zipped) FOR_EACH_ZIPPED_I(COMMA_SEPARATED, i, zipped) 

/*******************************************************************/ 
// DEMO: 

#define zipped (int, x, 10)(double, y, 20)(float, z, 30) 

FIRST: UNZIP(0, zipped) 
SECOND: UNZIP(1, zipped) 
THIRD: UNZIP(2, zipped) 

Präprozessorausgabe:

FIRST: int , double , float 
SECOND: x , y , z 
THIRD: 10 , 20 , 30 
4

Angenommen, Sie Kommas ((int,x),(double,y),(float,z)) gemeint, Boost.PP funktioniert super:

#include <boost/preprocessor.hpp> //or smaller individual headers 

//SEQ_ENUM adds commas between each element of the sequence 
//the sequence is transformed from what's passed into the ... 
//the invocation of UNZIP_MACRO is given the index to use in each element as data 
#define UNZIP(i, ...)        \ 
    BOOST_PP_SEQ_ENUM(       \ 
     BOOST_PP_SEQ_TRANSFORM(     \ 
      UNZIP_MACRO,       \ 
      i,         \ 
      BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \ 
     )           \ 
    ) 

//called with each element of the sequence 
#define UNZIP_MACRO(s, data, elem) \ 
    BOOST_PP_TUPLE_ELEM(data, elem) 


#define ZIPPED_SEQUENCE (int,x),(double,y),(float,z) 

UNZIP(0, ZIPPED_SEQUENCE) //int, double, float 
UNZIP(1, ZIPPED_SEQUENCE) //x, y, z