Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Эти пакеты разработаны для поддержки пакета fas/aop (в котором реализованы аспектно-ориентированные сущности), который я активно использую в реальных проектах уже более 8 лет. Если эта тема будет интересна, то я о ней тоже с удовольствием расскажу, но это потребует, возможно, целого цикла статей.
Кроме того boost::mpl работает с векторами, а faslib со списками
typedef boost::mpl::list<float,double,long double> floats;
typedef boost::mpl::push_front<floats,int>::type types;
/* types:
boost::mpl::l_item<mpl_::long_<4l>, int, boost::mpl::list3<float, double, long double> > */
typedef fas::type_list_n< float,double,long double>::type floats;
typedef fas::push_front< int, floats>::type types;
/* types:
fas::type_list<int, fas::type_list<float, fas::type_list<double, fas::type_list<long double, fas::empty_list> > > > */
- bool is_empty<Sequence>()
- {
- return false;
- }
- bool is_empty<Sequence>(typename boost::enable_if<boost::mpl::empty<Sequence>>::type * = 0)
- {
- return false;
- }
ИМХО, это правильно — позволяет менять внутреннее представление данных без изменений клиентского кода. Буст предоставляет интерфейс доступа аналогичный обычным контейнерав времени выполнения.В faslib во главе угла списки типов, могут меняться инструменты, но представление всегда одно. На ранних этапах я пытался скрыть представление, но отказался от этого.
Это плата за то что оно может работать на куче разных компиляторов, включая древние.Я не готов за это «платить» )
В бусте это специально сделано, чтоб можно было работать со сложными выражениями не упираясь в ограничение компилятора на максимальную вложенность шаблоновЭто не спасает от ограничения. Вы можете сколь угодно сложные конструкции, а в ограничение вы упретесь при обработке таких выражений. Опять же пример, строим «вектор» из 1600 элементов:
template<int I, typename List >
struct push {
typedef typename boost::mpl::push_front< List, fas::int_<I> >::type result;
typedef typename push< I-1, result>::type type;
};
template< typename List >
struct push<0, List> { typedef List type; };
int main()
{
typedef boost::mpl::vector<> lst;
typedef push<800, lst>::type lst800;
typedef push<800, lst800>::type lst1600;
std::cout << boost::mpl::size<lst800>::value << std::endl;
std::cout << boost::mpl::size<lst1600>::value << std::endl;
}
template<int I, typename List >
struct push2 {
typedef typename fas::push_front< fas::int_<I>, List >::type result;
typedef typename push2< I-1, result>::type type;
};
template< typename List >
struct push2<0, List> { typedef List type; };
int main()
{
typedef fas::empty_list lst;
typedef push2<800, lst>::type lst800;
typedef push2<800, lst800>::type lst1600;
std::cout << fas::length<lst800>::value << std::endl;
std::cout << fas::length<lst1600>::value << std::endl;
}
Кроме того, насколько я помню «вектора» быстрее компилируются обычно (не уверен, т.к. последний раз я в этом копался очень давно).
0m1.027s2m16.836s
faslib: 0m1.400s
boost: 16m58.397s
template <typename V>
class C{};
template <>
class C<mpl::vector<int> >{};
mpl::vector1<int> или mpl::vector<int>
- template <class V, class Enable = void>
- class C {};
- template <class C>
- class A<C, typename boost::enable_if<boost::mpl::equal<V, boost::mpl::vector<int> > >::type> {};
Для такой задачи есть стандартный механизм:Примерно так и работают операции со списками типов (в статье есть пример fas::lenght ), но плюс всегда есть специализация, для ускорения компиляции.
Справедливости ради, вместо вектора там вообще может быть все что угодно
A sequence s1 is said to be concept-identical to a sequence s2 if s1 and s2 model the exact same set of concepts.
mpl::vector1<int> и, уверен, 100 лет бы проработало, но формально — это ошибка.принимать конкретно ваши (fas::) списки типов
fas::switch_< fas::case_< fas::false_, fas::int_<24> >, fas::case_c< 1, fas::int_<42> >, fas::default_< fas::int_<44> > >::type::value
Крестики-нолики: компилятор против человека — экстремальный метапрограмминг