### Boost Install Example Source: https://github.com/boostorg/mp11/blob/develop/CMakeLists.txt Example of using boost_install to install the library headers. ```cmake boost_install(TARGETS boost_mp11 HEADER_DIRECTORY include/) ``` -------------------------------- ### Boost Fetch Example Source: https://github.com/boostorg/mp11/blob/develop/CMakeLists.txt Example of fetching BoostFetch.cmake and including it for dependency management. ```cmake file(DOWNLOAD "https://raw.githubusercontent.com/boostorg/cmake/develop/include/BoostFetch.cmake" "${CMAKE_BINARY_DIR}/fetch_and_include/BoostFetch.cmake" ) include("${CMAKE_BINARY_DIR}/fetch_and_include/BoostFetch.cmake") boost_fetch(boostorg/cmake TAG develop NO_ADD_SUBDIR) ``` -------------------------------- ### Example using meta_compose Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc An example of higher-order metaprogramming using meta_compose to compose metafunctions. ```cpp using outer = typelist_cat_t< typelist_transform_t< typelist...>, meta_compose< meta_quote, meta_quote_i, meta_quote > >; ``` -------------------------------- ### Example type list instantiation Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc An example of instantiating the mp_list with several fundamental types. ```cpp using list = mp_list; ``` -------------------------------- ### mp_rename usage examples Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Examples demonstrating the usage of mp_rename for various type transformations. ```cpp mp_rename, std::tuple> // -> std::tuple mp_rename, std::pair> // -> std::pair mp_rename, std::unique_ptr> // -> std::unique_ptr ``` -------------------------------- ### Tuple Cat Example Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc An example demonstrating the usage of `tuple_cat` with various tuple and pair types. ```cpp template void print_tuple( std::tuple const & tp ) { std::cout << "{"; print_tuple_<0, sizeof...(T), T...>()( tp ); std::cout << " }\n"; } int main() { std::tuple t1{ 1, 2 }; std::tuple<> t2; std::tuple t3{ 3, 4, 5 }; std::pair t4{ "pv", "test" }; using expected = std::tuple; auto result = ::tuple_cat( t1, t2, t3, t4 ); static_assert( std::is_same::value, "" ); print_tuple( result ); } ``` -------------------------------- ### Metaprogramming lambda library example Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc An example of defining a metafunction using a metaprogramming lambda library. ```cpp lambda<_a, _b, less, sizeof_<_b>>>> ``` -------------------------------- ### Example Usage of rvisit Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc A complete C++ example demonstrating the usage of the rvisit function with std::variant and std::visit, including helper functions for printing variant information. ```cpp #include #include #include #include #include #include using namespace boost::mp11; template using remove_cv_ref = typename std::remove_cv< typename std::remove_reference::type>::type; template auto rvisit( F&& f, V&&... v ) { using Qret = mp_bind_front; using R = mp_unique...>>; return std::visit( [&]( auto&&... x ) { return R( std::forward(f)( std::forward(x)... ) ); }, std::forward( v )... ); } template std::string name() { return boost::core::demangle( typeid(T).name() ); } template void print_variant( char const * n, V const& v ) { std::cout << "(" << name() << ")" << n << ": "; std::visit( []( auto const& x ) { std::cout << "(" << name() << ")" << x << std::endl; }, v ); } int main() { std::variant v1( 1 ); print_variant( "v1", v1 ); std::variant const v2( 3.14 ); print_variant( "v2", v2 ); auto v3 = rvisit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 ); print_variant( "v3", v3 ); } ``` -------------------------------- ### Using mp_flatten Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Examples demonstrating the usage of mp_flatten. ```cpp using L1 = tuple, void, tuple>; using R1 = mp_flatten; // tuple using L2 = mp_list, tuple>; using R2a = mp_flatten; // mp_list> using R2b = mp_flatten>; // mp_list, void> using L3 = mp_list, mp_list>>; using R3 = mp_flatten; // mp_list> ``` -------------------------------- ### Using mp_repeat_c Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Examples demonstrating the usage of mp_repeat_c. ```cpp using L1 = tuple; using R1 = mp_repeat_c; // tuple using L2 = pair; using R2 = mp_repeat_c; // pair using L3 = mp_list; using R3 = mp_repeat_c; // mp_list using L4 = mp_list; using R4 = mp_repeat_c; // mp_list<> using L5 = mp_list_v; using R5 = mp_repeat_c; // mp_list_v ``` -------------------------------- ### mp_split example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Demonstrates how mp_split works with different list and separator configurations. ```cpp template using mp_split = /*...*/; Splits the list `L` into segments at each separator `S` and returns a list of the segments. `mp_split, S>` is `L>`. `mp_split, S>`, where `S` does not occur in `T...`, is `L>`. `mp_split, S>` is `L, L, L>`. The segments may be empty; `mp_split, S>` is `L, L, L<>, L<>>`. ``` -------------------------------- ### mp_reverse example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Illustrates the reversal of a list using mp_reverse. ```cpp template using mp_reverse = /*...*/; `mp_reverse>` is `L`. ``` -------------------------------- ### Initial tuple_cat implementation Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc The initial implementation of `tuple_cat` as presented in the article. ```cpp template using F = mp_iota>; template R tuple_cat_( mp_list, mp_list, Tp tp ) { return R{ std::get(std::get(tp))... }; } template, typename std::remove_reference::type...>> R tuple_cat( Tp &&... tp ) { std::size_t const N = sizeof...(Tp); // inner using list1 = mp_list< mp_rename::type, mp_list>...>; using list2 = mp_iota_c; using list3 = mp_transform; using inner = mp_apply; // outer using list4 = mp_transform; using outer = mp_apply; // return tuple_cat_( inner(), outer(), std::forward_as_tuple( std::forward(tp)... ) ); } ``` -------------------------------- ### mp_partition_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_partition usage with a quoted metafunction. ```cpp template using mp_partition_q = mp_partition; As `mp_partition`, but takes a quoted metafunction. ``` -------------------------------- ### Using mp_front with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_front with mp_list_v. ```c++ using L4 = mp_list_v<1, 2, 3, 4>; using R4 = mp_front; // mp_int\<1> ``` -------------------------------- ### Using mp_iterate Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Examples demonstrating the usage of mp_iterate with different scenarios. ```C++ #include #include namespace mp = boost::mp11; struct X1 {}; struct X2 {}; struct X3 {}; using L1 = mp_list; using R1 = mp_iterate; // L1 struct nil {}; template struct cons {}; using V2 = mp_reverse_fold; // cons>> using R2 = mp_iterate; // L1 struct Y1 {}; struct Y2 { using value_type = double; using next_type = Y1; }; struct Y3 { using value_type = float; using next_type = Y2; }; struct Y4 { using value_type = int; using next_type = Y3; }; template using value_type = typename T::value_type; template using next_type = typename T::next_type; using R3 = mp_iterate; // mp_list using R4 = mp_iterate; // mp_list ``` -------------------------------- ### Using mp_front with mp_list Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_front with mp_list. ```c++ using L3 = mp_list; using R3 = mp_front; // char[1] ``` -------------------------------- ### Automated Test Case Generation with Mp11 Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc Demonstrates using Mp11's 'mp_product' and 'tuple_for_each' to automate the generation and execution of test cases for various type combinations. ```cpp #include #include #include #include #include using namespace boost::mp11; template std::string name() { return boost::core::demangle( typeid(T).name() ); } template using promote = typename std::common_type::type; template using result = typename std::common_type, promote>::type; template void test_result( mp_list const& ) { using T3 = decltype( T1() + T2() ); using T4 = result; std::cout << ( std::is_same::value? "[PASS] ": "[FAIL] " ) << name() << " + " << name() << " -> " << name() << ", result: " << name() << std::endl; } int main() { using L = std::tuple; tuple_for_each( mp_product(), [](auto&& x){ test_result(x); } ); } ``` -------------------------------- ### mp_partition example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Explains how mp_partition divides a list based on a predicate. ```cpp template class P> using mp_partition = /*...*/; `mp_partition, P>` partitions `L` into two lists `L` and `L` such that `mp_to_bool>` is `mp_true` for the elements of `L` and `mp_false` for the elements of `L`. Returns `L, L>`. ``` -------------------------------- ### mp_nth_element_c example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Explains how to get the nth element after sorting using mp_nth_element_c. ```cpp template class P> using mp_nth_element_c = /*...*/; Returns the element at position `I` in `mp_sort`. ``` -------------------------------- ### CMakeLists.txt Configuration Source: https://github.com/boostorg/mp11/blob/develop/test/cmake_install_test/CMakeLists.txt This is the main CMake configuration file for the test project. ```cmake cmake_minimum_required(VERSION 3.5...3.16) project(cmake_install_test LANGUAGES CXX) find_package(boost_mp11 REQUIRED) add_executable(main main.cpp) target_link_libraries(main Boost::mp11) enable_testing() add_test(NAME main COMMAND main) add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) ``` -------------------------------- ### Using mp_list_c Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_list_c to create a list of integers. ```c++ using L1 = mp_list_c; // mp_list, mp_int<3>> ``` -------------------------------- ### mp_nth_element_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Demonstrates mp_nth_element usage with a quoted metafunction. ```cpp template using mp_nth_element_q = /*...*/; Like `mp_nth_element`, but takes a quoted metafunction. ``` -------------------------------- ### mp_min_element_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_min_element usage with a quoted metafunction. ```cpp template using mp_min_element_q = mp_min_element; As `mp_min_element`, but takes a quoted metafunction. ``` -------------------------------- ### mp_sort example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Demonstrates sorting a list using mp_sort with a custom comparison. ```cpp template class P> using mp_sort = /*...*/; `mp_sort` sorts the list `L` according to the strict weak ordering `mp_to_bool>`. ``` -------------------------------- ### mp_find example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Demonstrates how mp_find locates the index of a specific type in a list. ```cpp template using mp_find = /*...*/; `mp_find` returns the index at which the type `V` is located in the list `L`. It's an alias for `mp_size_t`, where `I` is the zero-based index of the first occurrence of `V` in `L`. If `L` does not contain `V`, `mp_find` is `mp_size`. ``` -------------------------------- ### C++ template deduction example 2 Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming_2.adoc This example shows how to fix one template parameter when deducing from multiple std::pair base classes. ```cpp struct K1 {}; struct V1 {}; struct K2 {}; struct V2 {}; struct X: std::pair, std::pair {}; template void f(std::pair const & p); int main() { f(X()); } ``` -------------------------------- ### Example usage of mp_transform2 Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates how to use mp_transform2 with std::pair to transform a pair of tuples into a tuple of pairs. ```C++ using input = std::pair, std::tuple>; using expected = std::tuple, std::pair, std::pair>; using result = mp_transform2; static_assert( std::is_same::value, "" ); ``` -------------------------------- ### C++ template deduction example 1 Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming_2.adoc This example demonstrates how C++ can deduce template parameters of base classes when passed a derived class. ```cpp struct K1 {}; struct V1 {}; struct X: std::pair {}; template void f(std::pair const & p); int main() { f(X()); } ``` -------------------------------- ### mp_find_if_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_find_if usage with a quoted metafunction. ```cpp template using mp_find_if_q = mp_find_if; As `mp_find_if`, but takes a quoted metafunction. ``` -------------------------------- ### Using mp_front with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_front with std::tuple. ```c++ using L2 = std::tuple; using R2 = mp_front; // float ``` -------------------------------- ### Example usage of mp_transform with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates how to use mp_transform to transform elements of an std::tuple into pointers. ```cpp using input = std::tuple; using expected = std::tuple; using result = mp_transform; static_assert( std::is_same::value, "" ); ``` -------------------------------- ### mp_max_element_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_max_element usage with a quoted metafunction. ```cpp template using mp_max_element_q = mp_max_element; As `mp_max_element`, but takes a quoted metafunction. ``` -------------------------------- ### Using mp_front with std::pair Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_front with std::pair. ```c++ using L1 = std::pair; using R1 = mp_front; // int ``` -------------------------------- ### Using mp_fill with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Example of using mp_fill with mp_list_v. ```cpp using L1 = mp_list_v; using R1 = mp_fill>; // mp_list_v<7, 7> ``` -------------------------------- ### Using mp_clear with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_clear with mp_list_v. ```c++ using L1 = mp_list_v<0, true>; using R1 = mp_clear; // mp_list_v<> ``` -------------------------------- ### Fully operational tuple_cat implementation Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc This code snippet provides the complete implementation of the tuple_cat function, including helper templates and metaprogramming constructs. ```cpp template using F = mp_iota>; template R tuple_cat_( mp_list, mp_list, Tp tp ) { return R{ std::get(std::get(std::move(tp)))... }; } template using remove_cv_ref = typename std::remove_cv< typename std::remove_reference::type>::type; template using tuple_element = typename std::tuple_element::type; template using from_tuple_like = mp_product, mp_iota>>; template, from_tuple_like>...>> R tuple_cat( Tp &&... tp ) { std::size_t const N = sizeof...(Tp); // inner using list1 = mp_list>...>; using list2 = mp_iota_c; using list3 = mp_transform; using inner = mp_apply; // outer using list4 = mp_transform; using outer = mp_apply; // return tuple_cat_( inner(), outer(), std::forward_as_tuple( std::forward(tp)... ) ); } ``` -------------------------------- ### Using mp_cond Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/utility.adoc This example shows how to use mp_cond to select an unsigned integer type based on the size specified by an integer N. It provides a default case for unsigned integers. ```C++ template using unsigned_ = mp_cond< mp_bool, uint8_t, mp_bool, uint16_t, mp_bool, uint32_t, mp_bool, uint64_t, mp_true, unsigned // default case >; ``` -------------------------------- ### Example usage of mp_lambda Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/lambda.adoc Demonstrates how mp_lambda::fn replaces placeholders. ```c++ mp_lambda>::fn ``` -------------------------------- ### mp_join example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Illustrates the reverse operation of mp_split, joining segments with a separator. ```cpp template using mp_join = /*...*/; `mp_join` is the reverse operation of `mp_split`; it takes a list of segments `L` and joins them into a single list, inserting the separator `S` between them. `mp_join, S>` yields back the original list `L`. For example, `mp_split, S>` gives `L, L>`, and `mp_join, L>, S>` results in `L`. `mp_join` is equivalent to (and is implemented as) `mp_apply>>`. ``` -------------------------------- ### Using mp_size with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_size with mp_list_v. ```c++ using L4 = mp_list_v<1, false, 8ull>; using R4 = mp_size; // mp_size_t\<3> ``` -------------------------------- ### mp_sort_q example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_sort usage with a quoted metafunction. ```cpp template using mp_sort_q = mp_sort; As `mp_sort`, but takes a quoted metafunction. ``` -------------------------------- ### Using mp_eval_or to select the first pack element, or void Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/utility.adoc This example demonstrates how to use mp_eval_or to select the first element of a parameter pack, defaulting to void if the pack is empty or if mp_first fails. ```C++ template using first_or_void = mp_eval_or>; ``` -------------------------------- ### C++11 Compatible Test Case Generation Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc Provides a C++11 compatible version of the test case generation using a function object instead of a lambda. ```cpp struct test_result { template void operator()( mp_list const& ) const { using T3 = decltype( T1() + T2() ); using T4 = result; std::cout << ( std::is_same::value? "[PASS] ": "[FAIL] " ) << name() << " + " << name() << " -> " << name() << ", result: " << name() << std::endl; } }; int main() { using L = std::tuple; tuple_for_each( mp_product(), test_result() ); } ``` -------------------------------- ### mp_min_element example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Explains how mp_min_element finds the minimum element in a list based on a predicate. ```cpp template class P> using mp_min_element = /*...*/; `mp_min_element` returns the minimal element of the list `L` according to the ordering `mp_to_bool>`. It's equivalent to `mp_fold, mp_first, F>`, where `F` returns `mp_if, T, U>`. Supports a value list as `L` under {cpp}17. In that case, the element is returned wrapped with `mp_value`. ``` -------------------------------- ### Using mp_size with mp_list Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_size with an empty mp_list. ```c++ using L1 = mp_list<>; using R1 = mp_size; // mp_size_t\<0> ``` -------------------------------- ### Metafunction examples Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/definitions.adoc Examples of metafunctions using template aliases. ```cpp template using F1 = void; template using F2 = T*; template using F3 = std::integral_constant; ``` -------------------------------- ### mp_find_if example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Explains how mp_find_if finds the index of the first element satisfying a predicate. ```cpp template class P> using mp_find_if = /*...*/; `mp_find_f` is an alias for `mp_size_t`, where `I` is the zero-based index of the first element `T` in `L` for which `mp_to_bool>` is `mp_true`. If there is no such element, `mp_find_if` is `mp_size`. ``` -------------------------------- ### Example of const tuple failure Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc Demonstrates the failure when concatenating `const` tuples. ```cpp std::tuple const t1; std::tuple const t2; auto result = ::tuple_cat( t1, t2 ); ``` -------------------------------- ### Using mp_assign with value lists Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_assign with value lists. ```c++ using L1 = mp_list; using L2 = mp_list_v<0, false>; using R1 = mp_assign; // mp_list, mp_false> ``` -------------------------------- ### C++11 alias template for specific metafunction composition Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc An example of defining a composite metafunction using C++11 alias templates for specific metafunctions. ```cpp template using F = as_typelist_t::value>>; ``` -------------------------------- ### Using mp_quote to make a list of metafunctions Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/utility.adoc This example demonstrates how to use mp_quote to transform standard C++ template traits (like std::is_const and std::is_volatile) into a list of quoted metafunctions. ```C++ using LQ = mp_list, mp_quote>; ``` -------------------------------- ### rvisit implementation Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc A custom rvisit function template that allows std::visit to return a std::variant, handling cases where different combinations of variant values result in different return types. ```cpp template auto rvisit( F&& f, V&&... v ) { using Qret = mp_bind_front; using R = mp_unique...>>; return std::visit( [&]( auto&&... x ) { return R( std::forward(f)( std::forward(x)... ) ); }, std::forward( v )... ); } ``` -------------------------------- ### Example of move-only type failure Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc Demonstrates the failure when concatenating tuples with move-only types like `unique_ptr`. ```cpp std::tuple> t1; std::tuple> t2; auto result = ::tuple_cat( std::move( t1 ), std::move( t2 ) ); ``` -------------------------------- ### C++11 equivalent of meta_compose Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates how to achieve the same composition of metafunctions using C++11 alias templates. ```cpp template using Fgh = F>>; ``` -------------------------------- ### Quoted metafunction examples Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/definitions.adoc Examples of quoted metafunctions, which are classes with a public metafunction member called 'fn'. ```cpp struct Q1 { template using fn = void; }; struct Q2 { template using fn = T*; }; struct Q3 { template using fn = std::integral_constant; }; ``` -------------------------------- ### Example of std::array failure Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc Demonstrates the failure when concatenating `std::array` using the initial `tuple_cat` implementation. ```cpp std::array t1{ 1, 2 }; std::array t2{ 3.0f, 4.0f, 5.0f }; auto result = ::tuple_cat( t1, t2 ); ``` -------------------------------- ### mp_transform with unary and binary specializations Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates the unary and binary specializations for the variadic mp_transform, allowing it to handle different numbers of input lists. ```C++ template class F, class... L> struct mp_transform_impl; template class F, class... L> using mp_transform = typename mp_transform_impl::type; template class F, template class L, class... T> struct mp_transform_impl> { using type = L...>; }; template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> { static_assert( sizeof...(T1) == sizeof...(T2), "The arguments of mp_transform should be of the same size" ); using type = L1...>; }; ``` -------------------------------- ### Integral constant type example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/definitions.adoc An example of an integral constant type, which is a class with a public member 'value' that is an integral constant. ```cpp struct N { static int constexpr value = 2; }; ``` -------------------------------- ### Map examples Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/definitions.adoc Examples of maps, which are lists of lists where inner lists have at least one element (the key) and map keys are unique. ```cpp using M1 = std::tuple, std::pair, std::pair>; using M2 = mp_list, mp_list, mp_list>; ``` -------------------------------- ### _1 to _9 Placeholders Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/bind.adoc Placeholder types equivalent to boost::bind placeholders. ```cpp using _1 = mp_arg<0>; using _2 = mp_arg<1>; using _3 = mp_arg<2>; using _4 = mp_arg<3>; using _5 = mp_arg<4>; using _6 = mp_arg<5>; using _7 = mp_arg<6>; using _8 = mp_arg<7>; using _9 = mp_arg<8>; ``` -------------------------------- ### C++11 Type List Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates how C++11 variadic templates can be used to define a type list. ```cpp // C++11 template struct type_list {}; ``` -------------------------------- ### mp_nth_element example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Shows mp_nth_element with a type argument for the index. ```cpp template class P> using mp_nth_element = /*...*/; Like `mp_nth_element_c`, but with a type argument `I`. `I::value` must be a nonnegative number. ``` -------------------------------- ### Using mp_apply_q with mp_bind_front Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Shows how mp_apply_q, which takes a quoted metafunction, can be used with mp_bind_front to modify a list. ```cpp using L1 = std::tuple; using L2 = mp_list; using R1 = mp_apply_q, L2>; // R1 is std::tuple ``` -------------------------------- ### Using mp_push_front with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Demonstrates using mp_push_front to insert elements at the front of an mp_list_v. ```cpp using L3 = mp_list_v<0, 1>; using R3 = mp_push_front; // mp_list_v ``` -------------------------------- ### Using mp_push_front with mp_list Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Demonstrates using mp_push_front to insert elements at the front of an mp_list. ```cpp using L2 = mp_list; using R2 = mp_push_front; // mp_list ``` -------------------------------- ### mp_bind_front_q Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/bind.adoc Similar to mp_bind_front, but takes a quoted metafunction. ```cpp template using mp_bind_front_q = mp_bind_front; ``` -------------------------------- ### mp_all behavior Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/function.adoc Demonstrates the behavior of mp_all, which does not short-circuit and can result in compile-time errors. ```c++ using R1 = mp_all; // mp_true using R2 = mp_all; // compile-time error using R3 = mp_all; // mp_false using R4 = mp_all; // compile-time error ``` -------------------------------- ### Using mp_fill with std::pair Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Example of using mp_fill with std::pair. ```cpp using L1 = std::pair; using R1 = mp_fill; // std::pair ``` -------------------------------- ### Efficient Implementation of mp_at_c using Pack Expansion Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming_2.adoc An optimized implementation of `mp_at_c` that leverages pack expansion and a clever function signature to achieve better compile times. It uses `mp_repeat_c` to generate placeholder types and `mp_map_from_list` to create an intermediate map for lookup. ```cpp // mp_repeat_c template struct mp_repeat_c_impl { using _l1 = typename mp_repeat_c_impl::type; using _l2 = typename mp_repeat_c_impl::type; using type = mp_append<_l1, _l1, _l2>; }; template struct mp_repeat_c_impl<0, T...> { using type = mp_list<>; }; template struct mp_repeat_c_impl<1, T...> { using type = mp_list; }; template using mp_repeat_c = typename mp_repeat_c_impl::type; // mp_at template struct mp_at_c_impl; template class L, class... T, template class L2, class... U> struct mp_at_c_impl, L2> { template static W f( U*..., W*, ... ); using R = decltype( f( (mp_identity*)0 ... ) ); using type = typename R::type; }; template using mp_at_c = typename mp_at_c_impl>::type; template using mp_at = mp_at_c; ``` -------------------------------- ### Compile-time mp_find_index implementation using constexpr Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming_2.adoc An implementation using a constexpr function for better performance. ```c++ template struct mp_find_index_impl; template using mp_find_index = typename mp_find_index_impl::type; template class L, class V> struct mp_find_index_impl, V> { using type = mp_size_t<0>; }; constexpr std::size_t cx_find_index( bool const * first, bool const * last ) { return first == last || *first? 0: 1 + cx_find_index( first + 1, last ); } template class L, class... T, class V> struct mp_find_index_impl, V> { static constexpr bool _v[] = { std::is_same::value... }; using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; }; ``` -------------------------------- ### Using mp_fill with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Example of using mp_fill with std::tuple. ```cpp using L1 = std::tuple; using R1 = mp_fill; // std::tuple ``` -------------------------------- ### C++11 Metafunction using Template Alias Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Demonstrates the C++11 syntax for defining a metafunction as a template alias. ```cpp // C++11 template using add_pointer = T*; ``` -------------------------------- ### Using mp_pop_front with mp_list_v Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Demonstrates using mp_pop_front to remove the first element from an mp_list_v. ```cpp using L3 = mp_list_v<1, 2, 3, 4>; using R3 = mp_pop_front; // mp_list_v<2, 3, 4> ``` -------------------------------- ### mp_front Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Type trait to get the first element of a list. ```c++ template using mp_front = /*...*/; ``` -------------------------------- ### mp_and behavior Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/function.adoc Demonstrates the short-circuiting behavior of mp_and. ```c++ using R1 = mp_and; // mp_true using R2 = mp_and; // mp_false, void is not reached using R3 = mp_and; // mp_false using R4 = mp_and; // mp_false (!) ``` -------------------------------- ### mp_size Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Type trait to get the number of elements in a list. ```c++ template using mp_size = /*...*/; ``` -------------------------------- ### mp_transform_impl (pack expansion) Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc C++11 implementation of mp_transform leveraging pack expansion for conciseness. ```cpp template class F, class L> struct mp_transform_impl; template class F, class L> using mp_transform = typename mp_transform_impl::type; template class F, template class L, class... T> struct mp_transform_impl> { using type = L...>; }; ``` -------------------------------- ### mp_max_element example Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/algorithm.adoc Explains how mp_max_element finds the maximum element in a list based on a predicate. ```cpp template class P> using mp_max_element = /*...*/; `mp_max_element` returns the maximal element of the list `L` according to the ordering `mp_to_bool>`. It's equivalent to `mp_fold, mp_first, F>`, where `F` returns `mp_if, T, U>`. Supports a value list as `L` under {cpp}17. In that case, the element is returned wrapped with `mp_value`. ``` -------------------------------- ### Using mp_pop_front with mp_list Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Demonstrates using mp_pop_front to remove the first element from an mp_list. ```cpp using L2 = mp_list; using R2 = mp_pop_front; // mp_list<> ``` -------------------------------- ### mp_any behavior Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/function.adoc Demonstrates the behavior of mp_any, which does not short-circuit and can result in compile-time errors. ```c++ using R1 = mp_any; // mp_true using R2 = mp_any; // compile-time error using R3 = mp_any; // mp_false using R4 = mp_any; // compile-time error ``` -------------------------------- ### Using mp_clear with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_clear with std::tuple. ```c++ using L1 = std::tuple; using R1 = mp_clear; // std::tuple<> ``` -------------------------------- ### mp_push_front_impl (variadic) Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Variadic template implementation of mp_push_front that can add multiple elements to the front of a type list. ```cpp template struct mp_push_front_impl; template class L, class... U, class... T> struct mp_push_front_impl, T...> { using type = L; }; template using mp_push_front = typename mp_push_front_impl::type; ``` -------------------------------- ### CMakeLists.txt Source: https://github.com/boostorg/mp11/blob/develop/test/CMakeLists.txt The main CMakeLists.txt file for the Boost.mp11 project, handling build configuration and testing. ```cmake # Copyright 2018 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(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) if(HAVE_BOOST_TEST) boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::mp11 Boost::core) boost_test(SOURCES check_cmake_version.cpp ARGUMENTS ${PROJECT_VERSION} LINK_LIBRARIES Boost::core Boost::config) endif() ``` -------------------------------- ### Using mp_push_front with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Demonstrates using mp_push_front to insert elements at the front of a std::tuple. ```cpp using L1 = std::tuple; using R1 = mp_push_front; // std::tuple ``` -------------------------------- ### Using mp_empty with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Examples of using mp_empty with std::tuple. ```c++ using L1 = std::tuple; using R1 = mp_empty; // mp_false using L2 = std::tuple<>; using R2 = mp_empty; // mp_true ``` -------------------------------- ### mp_bind_back_q Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/bind.adoc Similar to mp_bind_back, but takes a quoted metafunction. ```cpp template using mp_bind_back_q = mp_bind_back; ``` -------------------------------- ### Using mp_size with std::tuple Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_size with std::tuple. ```c++ using L3 = std::tuple; using R3 = mp_size; // mp_size_t\<1> ``` -------------------------------- ### Using mp_size with std::pair Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/list.adoc Example of using mp_size with std::pair. ```c++ using L2 = std::pair; using R2 = mp_size; // mp_size_t\<2> ``` -------------------------------- ### Using mp_invoke_q to invoke a list of metafunctions, technique 3 Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/utility.adoc This technique uses mp_invoke_q with mp_apply and mp_transform, utilizing mp_fill to create a list of arguments for each quoted metafunction in LQ, with T as the argument. ```C++ template using is_const_and_volatile = mp_apply>>; ``` -------------------------------- ### mp_push_front_impl (single element) Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Implementation of mp_push_front for adding a single element to the front of a type list. ```cpp template struct mp_push_front_impl; template class L, class... U, class T> struct mp_push_front_impl, T> { using type = L; }; template using mp_push_front = typename mp_push_front_impl::type; ``` -------------------------------- ### Metafunction `from_tuple_like` Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc A metafunction to convert an arbitrary tuple-like type into an `mp_list` of its element types. ```cpp template using tuple_element = typename std::tuple_element::type; template using from_tuple_like = mp_product, mp_iota>>; ``` -------------------------------- ### mp_size in terms of mp_length Source: https://github.com/boostorg/mp11/blob/develop/doc/article/simple_cxx11_metaprogramming.adoc Implementation of mp_size using mp_length. ```C++ template class L, class... T> struct mp_size_impl> { using type = mp_length; }; ``` -------------------------------- ### Helper metafunction `remove_cv_ref` Source: https://github.com/boostorg/mp11/blob/develop/doc/mp11/examples.adoc A helper metafunction to remove `const` and reference qualifiers from a type. ```cpp template using remove_cv_ref = typename std::remove_cv< typename std::remove_reference::type>::type; ```