...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The BOOST_VMD_ELEM macro, which by default just returns an element of a sequence, has a usage where you can have it return both the element and the remaining part of the sequence after the element, or even just the remaining part of the sequence after the element by itself. This offers a form of splitting the sequence on a particular element. When used to return the remaining part of a sequence the remaining data may subsequently be treated as a VMD sequence again.
To do this another set of optional modifiers are used which will be called 'splitting modifers'. These modifiers are:
If more than one of the splitting modifiers are specified as optional parameters to BOOST_VMD_ELEM the last one specified is in effect.
The splitting modifiers BOOST_VMD_RETURN_NO_AFTER and BOOST_VMD_RETURN_AFTER work with either return type modifiers or filtering modifiers if they are used. The splitting modifier BOOST_VMD_RETURN_ONLY_AFTER works with filtering modifiers if it is used and any return type modifiers will be ignored. Optional modifiers may occur in any order after the required parameters to BOOST_VMD_ELEM.
If BOOST_VMD_RETURN_AFTER is in effect and an element is not found, either because the element number is out of range for the sequence or because filtering does not match the element type, a tuple will still be returned but both its elements will be empty.
#include <boost/vmd/elem.hpp> #define BOOST_VMD_REGISTER_ANAME (ANAME) // an identifier must always be registered to be found by VMD #define A_SEQUENCE (1,2,3) 46 (list_data1,BOOST_PP_NIL) BOOST_VMD_TYPE_SEQ ANAME BOOST_VMD_ELEM(2,A_SEQUENCE) will return '(list_data1,BOOST_PP_NIL)' BOOST_VMD_ELEM(2,A_SEQUENCE,BOOST_VMD_RETURN_NO_AFTER) will return '(list_data1,BOOST_PP_NIL)' BOOST_VMD_ELEM(2,A_SEQUENCE,BOOST_VMD_RETURN_AFTER) will return '((list_data1,BOOST_PP_NIL),BOOST_VMD_TYPE_SEQ ANAME)' BOOST_VMD_ELEM(2,A_SEQUENCE,BOOST_VMD_RETURN_ONLY_AFTER) will return 'BOOST_VMD_TYPE_SEQ ANAME' BOOST_VMD_ELEM(5,A_SEQUENCE) will return emptiness BOOST_VMD_ELEM(5,A_SEQUENCE,BOOST_VMD_RETURN_NO_AFTER) will return emptiness BOOST_VMD_ELEM(5,A_SEQUENCE,BOOST_VMD_RETURN_AFTER) will return '(,)' BOOST_VMD_ELEM(5,A_SEQUENCE,BOOST_VMD_RETURN_ONLY_AFTER) will return emptiness
Combining splitting modifiers with return type modifiers:
BOOST_VMD_ELEM(2,A_SEQUENCE,BOOST_VMD_RETURN_AFTER,BOOST_VMD_RETURN_TYPE) will return '((BOOST_VMD_TYPE_LIST,(list_data1,BOOST_PP_NIL)),BOOST_VMD_TYPE_SEQ ANAME)'
Combining splitting modifiers with filtering modifiers:
BOOST_VMD_ELEM(2,A_SEQUENCE,BOOST_VMD_RETURN_AFTER,BOOST_VMD_TYPE_LIST) will return '((list_data1,BOOST_PP_NIL),BOOST_VMD_TYPE_SEQ ANAME)'