Generation of huge sequences like Boost.MPL

Consider the following code that automates the generation of sequences of types Boost.MPL (list or vector).

#include <iostream> // cout #include <boost/mpl/for_each.hpp> // for_each #include <boost/mpl/identity.hpp> // identity, make_identity #include <boost/mpl/int.hpp> // int_ #include <boost/mpl/list.hpp> // list #include <boost/mpl/next.hpp> // next #include <boost/mpl/push_front.hpp> // push_front #include <boost/mpl/vector.hpp> // vector template<size_t, typename> struct iota_n; template<typename Value> struct iota_n<0, Value> : boost::mpl::list<> // can change this to boost::mpl::vector<> {}; template<size_t N, typename Value> struct iota_n : boost::mpl::push_front< typename iota_n< N - 1, typename boost::mpl::next<Value>::type >::type, Value > {}; // works for N <= 20 and boost::mpl::vector // works for N <= 247 and boost::mpl::list typedef iota_n< 247, boost::mpl::int_<0> >::type sequence; struct print { template<typename T> void operator()(boost::mpl::identity<T>) { std::cout << T::value << "\n"; } }; int main() { boost::mpl::for_each<sequence, boost::mpl::make_identity<> >( print() ); std::cout << BOOST_MPL_LIMIT_LIST_SIZE << '\n'; // 20 on my system std::cout << BOOST_MPL_LIMIT_VECTOR_SIZE << '\n'; // 20 on my system return 0; } 

According to the Boost.MPL documentation, the boost::mpl::list sequence can have up to BOOST_MPL_LIMIT_LIST_SIZE elements, and similarly for boost::mpl::vector compiler can switch to BOOST_MPL_LIMIT_VECTOR_SIZE . Both macros evaluate to 20 on my system.

MSVC ++ 2010 and Boost 1.47.0 really cannot generate vectors with more than 20 documented elements. However, it is surprising that it can generate lists with 247 items!

Does anyone know why this is happening?

+4
source share
1 answer

According to docs , BOOST_MPL_LIMIT_xxx_SIZE indicates the limit for the variational form of the sequence (for example, list<> ); a numbered form (for example, list42<> ) does not have a predefined upper limit, except for the compiler's restrictions on the number of template parameters. Well, the last statement is not entirely accurate: in practice, in the default library configuration, there is a limit for numbered forms superimposed using pre-formed pre-processed headers; see this post on how to remove it.

FOLLOW UP: @rhalbersma. It seems that you combine two separate concepts: the maximum number of list elements and the maximum arity of the list constructor. BOOST_MPL_LIMIT_LIST_SIZE controls the last , not the first, and there is no relationship between them. Your code above checks the first; maximum template arity is a completely different beast.

The reason that there is a limitation on arity for MPL sequences is because the library had to emulate variable patterns (it was written before C ++ 11), which usually runs by default unused arguments for some auxiliary type and providing a bunch of specializations for cutting off these unused arguments before building the actual sequence . The cost of this is that default arguments usually appear in error messages and hide everything else, and a large number of specializations have a noticeable effect on compilation time. IOW, you had to stop somewhere, and at that time it seemed unlikely that you often had to pass more than 20 elements of the sequence to the "constructor" sequence (and if you did, there were always numbered forms), therefore, the current limits.

+5
source

Source: https://habr.com/ru/post/1399102/


All Articles