forked from boostorg/mp11
Add mp_iota, mp_at, mp_take.
This commit is contained in:
@@ -49,6 +49,8 @@ template<class T, T N> struct make_integer_sequence_impl_
|
||||
{
|
||||
private:
|
||||
|
||||
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
|
||||
|
||||
static T const M = N / 2;
|
||||
static T const R = N % 2;
|
||||
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/mp_map_find.hpp>
|
||||
#include <boost/integer_sequence.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <type_traits>
|
||||
@@ -247,8 +249,66 @@ template<class L, std::size_t N> using mp_drop_c = typename detail::mp_drop_impl
|
||||
|
||||
template<class L, class N> using mp_drop = typename detail::mp_drop_impl<L, mp_repeat<mp_list<void>, N>>::type;
|
||||
|
||||
// mp_take(_c)<L, N>
|
||||
// mp_iota(_c)<N>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S> struct mp_from_sequence_impl;
|
||||
|
||||
template<template<class T, T... I> class S, class U, U... J> struct mp_from_sequence_impl<S<U, J...>>
|
||||
{
|
||||
using type = mp_list<std::integral_constant<U, J>...>;
|
||||
};
|
||||
|
||||
template<class S> using mp_from_sequence = typename mp_from_sequence_impl<S>::type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<std::size_t N> using mp_iota_c = detail::mp_from_sequence<make_index_sequence<N>>;
|
||||
template<class N> using mp_iota = detail::mp_from_sequence<make_integer_sequence<typename std::remove_const<decltype(N::value)>::type, N::value>>;
|
||||
|
||||
// mp_at(_c)<L, I>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class I> struct mp_at_impl
|
||||
{
|
||||
static_assert( I::value >= 0, "mp_at<L, I>: I must not be negative" );
|
||||
|
||||
using _map = mp_transform<mp_list, mp_iota<mp_size<L>>, L>;
|
||||
|
||||
using type = mp_second<mp_map_find<_map, mp_size_t<I::value>>>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, std::size_t I> using mp_at_c = typename detail::mp_at_impl<L, mp_size_t<I>>::type;
|
||||
|
||||
template<class L, class I> using mp_at = typename detail::mp_at_impl<L, I>::type;
|
||||
|
||||
// mp_take(_c)<L, N>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class N> struct mp_take_impl
|
||||
{
|
||||
static_assert( N::value >= 0, "mp_take<L, N>: N must not be negative" );
|
||||
|
||||
using _map = mp_transform<mp_list, mp_iota<mp_size<L>>, L>;
|
||||
|
||||
template<class I> using _f = mp_second<mp_map_find<_map, I>>;
|
||||
|
||||
using _ind = mp_iota_c<N::value>;
|
||||
|
||||
using type = mp_assign<L, mp_transform<_f, _ind>>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, std::size_t N> using mp_take_c = typename detail::mp_take_impl<L, mp_size_t<N>>::type;
|
||||
|
||||
template<class L, class N> using mp_take = typename detail::mp_take_impl<L, N>::type;
|
||||
|
||||
// mp_find<L, V>
|
||||
// mp_find_if<L, P>
|
||||
// mp_find_index<L, V>
|
||||
|
40
include/boost/mp11/detail/mp_map_find.hpp
Normal file
40
include/boost/mp11/detail/mp_map_find.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// mp_map_find
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class M, class K> struct mp_map_find_impl;
|
||||
|
||||
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
|
||||
{
|
||||
using U = mp_inherit<mp_identity<T>...>;
|
||||
|
||||
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
|
||||
static mp_identity<void> f( ... );
|
||||
|
||||
using V = decltype( f((U*)0) );
|
||||
|
||||
using type = typename V::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
@@ -9,7 +9,7 @@
|
||||
import testing ;
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
REQ = ; #[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_hdr_type_traits cxx11_hdr_tuple ] ;
|
||||
REQ = ; #[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_hdr_type_traits cxx11_hdr_tuple ] ;
|
||||
|
||||
# include-only
|
||||
compile mp11.cpp : : : $(REQ) ;
|
||||
@@ -35,6 +35,9 @@ run mp_contains.cpp : : : $(REQ) ;
|
||||
run mp_repeat.cpp : : : $(REQ) ;
|
||||
run mp_product.cpp : : : $(REQ) ;
|
||||
run mp_drop.cpp : : : $(REQ) ;
|
||||
run mp_iota.cpp : : : $(REQ) ;
|
||||
run mp_at.cpp : : : $(REQ) ;
|
||||
run mp_take.cpp : : : $(REQ) ;
|
||||
|
||||
# integral
|
||||
run integral.cpp : : : $(REQ) ;
|
||||
|
74
test/mp_at.cpp
Normal file
74
test/mp_at.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
struct X5 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp_list;
|
||||
using boost::mp_at;
|
||||
using boost::mp_at_c;
|
||||
using boost::mp_size_t;
|
||||
|
||||
{
|
||||
using L1 = mp_list<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 0>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 1>, X2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 2>, X3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 3>, X4>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 4>, X5>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<0>>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<1>>, X2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<2>>, X3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<3>>, X4>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<4>>, X5>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 0>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 1>, X2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 2>, X3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 3>, X4>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 4>, X5>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<0>>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<1>>, X2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<2>>, X3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<3>>, X4>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<4>>, X5>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::pair<X1, X2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 0>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at_c<L1, 1>, X2>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<0>>, X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_at<L1, mp_size_t<1>>, X2>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
42
test/mp_iota.cpp
Normal file
42
test/mp_iota.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp_list;
|
||||
using boost::mp_iota;
|
||||
using boost::mp_iota_c;
|
||||
using boost::mp_int;
|
||||
using boost::mp_size_t;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<0>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<1>, mp_list<mp_size_t<0>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<2>, mp_list<mp_size_t<0>, mp_size_t<1>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<3>, mp_list<mp_size_t<0>, mp_size_t<1>, mp_size_t<2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<4>, mp_list<mp_size_t<0>, mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_size_t<0>>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_size_t<1>>, mp_list<mp_size_t<0>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_size_t<2>>, mp_list<mp_size_t<0>, mp_size_t<1>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_size_t<3>>, mp_list<mp_size_t<0>, mp_size_t<1>, mp_size_t<2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_size_t<4>>, mp_list<mp_size_t<0>, mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_int<0>>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_int<1>>, mp_list<mp_int<0>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_int<2>>, mp_list<mp_int<0>, mp_int<1>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_int<3>>, mp_list<mp_int<0>, mp_int<1>, mp_int<2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota<mp_int<4>>, mp_list<mp_int<0>, mp_int<1>, mp_int<2>, mp_int<3>>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
85
test/mp_take.cpp
Normal file
85
test/mp_take.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
struct X5 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp_list;
|
||||
using boost::mp_take;
|
||||
using boost::mp_take_c;
|
||||
using boost::mp_size_t;
|
||||
|
||||
{
|
||||
using L1 = mp_list<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L1, mp_size_t<0>>, L1>));
|
||||
|
||||
using L2 = mp_list<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 0>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 1>, mp_list<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 2>, mp_list<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 3>, mp_list<X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 4>, mp_list<X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 5>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<0>>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<1>>, mp_list<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<2>>, mp_list<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<3>>, mp_list<X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<4>>, mp_list<X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<5>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L1, mp_size_t<0>>, L1>));
|
||||
|
||||
using L2 = std::tuple<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 0>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 1>, std::tuple<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 2>, std::tuple<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 3>, std::tuple<X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 4>, std::tuple<X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L2, 5>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<0>>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<1>>, std::tuple<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<2>>, std::tuple<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<3>>, std::tuple<X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<4>>, std::tuple<X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L2, mp_size_t<5>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::pair<X1, X2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_take<L1, mp_size_t<2>>, L1>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user