rename chapters
This commit is contained in:
@@ -11,7 +11,7 @@ set(CMAKE_SIZE "arm-none-eabi-size")
|
||||
set(RENODE "renode" CACHE STRING "Path to Renode executable")
|
||||
|
||||
set(MAIN_CPP_PATH "${CMAKE_SOURCE_DIR}/app/src/")
|
||||
set(MAIN_CPP_FILE_NAME "main_fsm_simple.cpp" CACHE STRING "main file")
|
||||
set(MAIN_CPP_FILE_NAME "main.cpp" CACHE STRING "main file")
|
||||
list(APPEND LIB_SPECS "-specs=nosys.specs")
|
||||
list(APPEND LIB_SPECS "-specs=nano.specs")
|
||||
|
||||
@@ -85,11 +85,10 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/app/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/uart/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/gpio/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/adc/inc
|
||||
${CMAKE_SOURCE_DIR}/cstdlib_support
|
||||
${CMAKE_SOURCE_DIR}/util/inc
|
||||
${CMAKE_SOURCE_DIR}/libs/boost
|
||||
${CMAKE_SOURCE_DIR}/libs
|
||||
)
|
||||
|
||||
set(EXECUTABLE ${PROJECT_NAME}.elf)
|
||||
@@ -108,8 +107,6 @@ add_executable(
|
||||
platform/src/stm32f0xx_hal_msp.c
|
||||
platform/src/stm32f0xx_it.c
|
||||
platform/src/system_stm32f0xx.c
|
||||
hal/gpio/src/gpio.cpp
|
||||
hal/gpio/src/gpio_interrupt_manager.cpp
|
||||
hal/adc/src/adc_stm32.cpp
|
||||
cstdlib_support/retarget.cpp
|
||||
util/src/units.cpp
|
||||
@@ -118,6 +115,8 @@ add_executable(
|
||||
|
||||
target_link_libraries(${EXECUTABLE} PUBLIC)
|
||||
|
||||
target_compile_definitions(${EXECUTABLE} PUBLIC "-DSIMULATE_FREESTANDING")
|
||||
|
||||
target_include_directories(${EXECUTABLE} PUBLIC ${PROJECT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR})
|
||||
|
||||
@@ -131,6 +130,8 @@ target_link_options(
|
||||
-mthumb
|
||||
${LIB_SPECS}
|
||||
-lnosys
|
||||
-u
|
||||
_printf_float
|
||||
-lc
|
||||
-lm
|
||||
-Wl,--no-warn-rwx-segments
|
||||
119
Chapter17/cib/app/src/main.cpp
Normal file
119
Chapter17/cib/app/src/main.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <stm32f072xb.h>
|
||||
|
||||
#include <hal.hpp>
|
||||
#include <stm32f0xx_hal_uart.hpp>
|
||||
#include <uart_stm32.hpp>
|
||||
|
||||
#include <retarget.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <cib/cib.hpp>
|
||||
|
||||
struct runtime_init : public flow::service<> {};
|
||||
|
||||
struct main_loop : public callback::service<> {};
|
||||
|
||||
struct send_temperature : public callback::service<float> {};
|
||||
|
||||
struct i2c {
|
||||
|
||||
constexpr static auto init = flow::action<"i2c_init">(
|
||||
[](){
|
||||
printf("I2C init ...\r\n");
|
||||
});
|
||||
|
||||
constexpr static auto config = cib::config(
|
||||
cib::extend<runtime_init>(*init)
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
struct temperature_sensor_component {
|
||||
|
||||
constexpr static auto init = flow::action<"temp_sensor_init">(
|
||||
[]() {
|
||||
printf("Initializing temperature sensor ... \r\n");
|
||||
});
|
||||
|
||||
constexpr static auto read_temperature = []() {
|
||||
float temperature = 23.4f;
|
||||
|
||||
cib::service<send_temperature>(temperature);
|
||||
};
|
||||
|
||||
constexpr static auto config = cib::config(
|
||||
cib::extend<main_loop>(read_temperature),
|
||||
|
||||
cib::extend<runtime_init>(i2c::init >> *init)
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
struct display_temperature_component {
|
||||
|
||||
constexpr static auto display_temperature = [](float temperature) {
|
||||
printf("Temperature is %.2f C\r\n", temperature);
|
||||
};
|
||||
|
||||
constexpr static auto config = cib::config(
|
||||
cib::extend<send_temperature>(display_temperature)
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
struct data_sender_component {
|
||||
|
||||
constexpr static auto send_temp = [](float temp) {
|
||||
printf("Sending temperature %.2f C\r\n", temp);
|
||||
};
|
||||
|
||||
constexpr static auto config = cib::config(
|
||||
cib::extend<send_temperature>(send_temp)
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
struct my_project {
|
||||
|
||||
constexpr static auto config = cib::config(
|
||||
cib::exports<runtime_init,
|
||||
main_loop,
|
||||
send_temperature>,
|
||||
|
||||
cib::components<i2c,
|
||||
temperature_sensor_component,
|
||||
display_temperature_component,
|
||||
data_sender_component>
|
||||
);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
hal::init();
|
||||
|
||||
hal::uart_stm32<hal::stm32::uart> uart(USART2);
|
||||
uart.init();
|
||||
|
||||
retarget::set_stdio_uart(&uart);
|
||||
|
||||
cib::nexus<my_project> nexus{};
|
||||
nexus.init();
|
||||
|
||||
nexus.service<runtime_init>();
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
nexus.service<main_loop>();
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
}
|
||||
}
|
||||
22
Chapter17/cib/libs/boost/mp11.hpp
Normal file
22
Chapter17/cib/libs/boost/mp11.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef BOOST_MP11_HPP_INCLUDED
|
||||
#define BOOST_MP11_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/list.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/map.hpp>
|
||||
#include <boost/mp11/set.hpp>
|
||||
#include <boost/mp11/bind.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_MP11_HPP_INCLUDED
|
||||
1327
Chapter17/cib/libs/boost/mp11/algorithm.hpp
Normal file
1327
Chapter17/cib/libs/boost/mp11/algorithm.hpp
Normal file
File diff suppressed because it is too large
Load Diff
111
Chapter17/cib/libs/boost/mp11/bind.hpp
Normal file
111
Chapter17/cib/libs/boost/mp11/bind.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef BOOST_MP11_BIND_HPP_INCLUDED
|
||||
#define BOOST_MP11_BIND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 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 <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_bind_front
|
||||
template<template<class...> class F, class... T> struct mp_bind_front
|
||||
{
|
||||
// the indirection through mp_defer works around the language inability
|
||||
// to expand U... into a fixed parameter list of an alias template
|
||||
|
||||
template<class... U> using fn = typename mp_defer<F, T..., U...>::type;
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>;
|
||||
|
||||
// mp_bind_back
|
||||
template<template<class...> class F, class... T> struct mp_bind_back
|
||||
{
|
||||
template<class... U> using fn = typename mp_defer<F, U..., T...>::type;
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>;
|
||||
|
||||
// mp_arg
|
||||
template<std::size_t I> struct mp_arg
|
||||
{
|
||||
template<class... T> using fn = mp_at_c<mp_list<T...>, I>;
|
||||
};
|
||||
|
||||
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>;
|
||||
|
||||
// mp_bind
|
||||
template<template<class...> class F, class... T> struct mp_bind;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class V, class... T> struct eval_bound_arg
|
||||
{
|
||||
using type = V;
|
||||
};
|
||||
|
||||
template<std::size_t I, class... T> struct eval_bound_arg<mp_arg<I>, T...>
|
||||
{
|
||||
using type = typename mp_arg<I>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_front<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind_front<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_back<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind_back<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_bind
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 )
|
||||
private:
|
||||
|
||||
template<class... U> struct _f { using type = F<typename detail::eval_bound_arg<T, U...>::type...>; };
|
||||
|
||||
public:
|
||||
|
||||
template<class... U> using fn = typename _f<U...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class... U> using fn = F<typename detail::eval_bound_arg<T, U...>::type...>;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED
|
||||
149
Chapter17/cib/libs/boost/mp11/detail/config.hpp
Normal file
149
Chapter17/cib/libs/boost/mp11/detail/config.hpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
||||
// Copyright 2016, 2018, 2019 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
|
||||
|
||||
// BOOST_MP11_WORKAROUND
|
||||
|
||||
#if defined( BOOST_STRICT_CONFIG ) || defined( BOOST_MP11_NO_WORKAROUNDS )
|
||||
|
||||
# define BOOST_MP11_WORKAROUND( symbol, test ) 0
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_MP11_WORKAROUND( symbol, test ) ((symbol) != 0 && ((symbol) test))
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
#define BOOST_MP11_CUDA 0
|
||||
#define BOOST_MP11_CLANG 0
|
||||
#define BOOST_MP11_INTEL 0
|
||||
#define BOOST_MP11_GCC 0
|
||||
#define BOOST_MP11_MSVC 0
|
||||
|
||||
#define BOOST_MP11_CONSTEXPR constexpr
|
||||
|
||||
#if defined( __CUDACC__ )
|
||||
|
||||
// nvcc
|
||||
|
||||
# undef BOOST_MP11_CUDA
|
||||
# define BOOST_MP11_CUDA (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__)
|
||||
|
||||
// CUDA (8.0) has no constexpr support in msvc mode:
|
||||
# if defined(_MSC_VER) && (BOOST_MP11_CUDA < 9000000)
|
||||
|
||||
# define BOOST_MP11_NO_CONSTEXPR
|
||||
|
||||
# undef BOOST_MP11_CONSTEXPR
|
||||
# define BOOST_MP11_CONSTEXPR
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
// Clang
|
||||
|
||||
# undef BOOST_MP11_CLANG
|
||||
# define BOOST_MP11_CLANG (__clang_major__ * 100 + __clang_minor__)
|
||||
|
||||
# if defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#if BOOST_MP11_CLANG < 400 && __cplusplus >= 201402L \
|
||||
&& defined( __GLIBCXX__ ) && !__has_include(<shared_mutex>)
|
||||
|
||||
// Clang pre-4 in C++14 mode, libstdc++ pre-4.9, ::gets is not defined,
|
||||
// but Clang tries to import it into std
|
||||
|
||||
extern "C" char *gets (char *__s);
|
||||
#endif
|
||||
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
|
||||
// Intel C++
|
||||
|
||||
# undef BOOST_MP11_INTEL
|
||||
# define BOOST_MP11_INTEL __INTEL_COMPILER
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// g++
|
||||
|
||||
# undef BOOST_MP11_GCC
|
||||
# define BOOST_MP11_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
// MS Visual C++
|
||||
|
||||
# undef BOOST_MP11_MSVC
|
||||
# define BOOST_MP11_MSVC _MSC_VER
|
||||
|
||||
# if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
# define BOOST_MP11_NO_CONSTEXPR
|
||||
# endif
|
||||
|
||||
#if _MSC_FULL_VER < 190024210 // 2015u3
|
||||
# undef BOOST_MP11_CONSTEXPR
|
||||
# define BOOST_MP11_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_CXX14_CONSTEXPR
|
||||
|
||||
#if !defined(BOOST_MP11_NO_CONSTEXPR) && defined(__cpp_constexpr) && __cpp_constexpr >= 201304
|
||||
# define BOOST_MP11_HAS_CXX14_CONSTEXPR
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
|
||||
#if !defined(BOOST_MP11_HAS_FOLD_EXPRESSIONS) && defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_TYPE_PACK_ELEMENT
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__type_pack_element)
|
||||
# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
|
||||
#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L
|
||||
# define BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
#endif
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
// mp_value<0> is bool, mp_value<-1L> is int, etc
|
||||
# undef BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_DEPRECATED(msg)
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 )
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#else
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
321
Chapter17/cib/libs/boost/mp11/detail/mp_append.hpp
Normal file
321
Chapter17/cib/libs/boost/mp11/detail/mp_append.hpp
Normal file
@@ -0,0 +1,321 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 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/detail/mp_count.hpp>
|
||||
#include <boost/mp11/detail/mp_is_value_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list_v.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_append<L...>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// append_type_lists
|
||||
|
||||
template<class... L> struct mp_append_impl;
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<class... L> struct mp_append_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_append_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_append_impl<L1<T1...>, L2<T2...>>
|
||||
{
|
||||
using type = L1<T1..., T2...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, template<class...> class L5, class... T5, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, Lr...>
|
||||
{
|
||||
using type = typename mp_append_impl<L1<T1..., T2..., T3..., T4..., T5...>, Lr...>::type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class L1 = mp_list<>, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
template<class...> class L1, class... T1,
|
||||
template<class...> class L2, class... T2,
|
||||
template<class...> class L3, class... T3,
|
||||
template<class...> class L4, class... T4,
|
||||
template<class...> class L5, class... T5,
|
||||
template<class...> class L6, class... T6,
|
||||
template<class...> class L7, class... T7,
|
||||
template<class...> class L8, class... T8,
|
||||
template<class...> class L9, class... T9,
|
||||
template<class...> class L10, class... T10,
|
||||
template<class...> class L11, class... T11>
|
||||
|
||||
struct append_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>,
|
||||
class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>,
|
||||
class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>,
|
||||
class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>,
|
||||
class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>,
|
||||
class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>,
|
||||
class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>,
|
||||
class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>,
|
||||
class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>,
|
||||
class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>,
|
||||
class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<>
|
||||
|
||||
> struct append_111_impl
|
||||
{
|
||||
using type = typename append_11_impl<
|
||||
|
||||
typename append_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
|
||||
typename append_11_impl<mp_list<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
|
||||
typename append_11_impl<mp_list<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
|
||||
typename append_11_impl<mp_list<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
|
||||
typename append_11_impl<mp_list<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
|
||||
typename append_11_impl<mp_list<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
|
||||
typename append_11_impl<mp_list<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
|
||||
typename append_11_impl<mp_list<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
|
||||
typename append_11_impl<mp_list<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
|
||||
typename append_11_impl<mp_list<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
|
||||
typename append_11_impl<mp_list<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
|
||||
|
||||
>::type;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
|
||||
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
|
||||
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
|
||||
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
|
||||
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
|
||||
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
|
||||
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
|
||||
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
|
||||
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
|
||||
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
|
||||
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
|
||||
class... Lr
|
||||
|
||||
> struct append_inf_impl
|
||||
{
|
||||
using prefix = typename append_111_impl<
|
||||
|
||||
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
|
||||
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
|
||||
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
|
||||
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
|
||||
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
|
||||
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
|
||||
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
|
||||
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
|
||||
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
|
||||
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
|
||||
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
|
||||
|
||||
>::type;
|
||||
|
||||
using type = typename mp_append_impl<prefix, Lr...>::type;
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<class... L>
|
||||
struct mp_append_impl_cuda_workaround
|
||||
{
|
||||
using type = mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >;
|
||||
};
|
||||
|
||||
template<class... L> struct mp_append_impl: mp_append_impl_cuda_workaround<L...>::type::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class... L> struct mp_append_impl:
|
||||
mp_cond<
|
||||
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_inf_impl>,
|
||||
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_111_impl>,
|
||||
mp_true, mp_quote<append_11_impl>
|
||||
>::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
struct append_type_lists
|
||||
{
|
||||
template<class... L> using fn = typename mp_append_impl<L...>::type;
|
||||
};
|
||||
|
||||
// append_value_lists
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<class... L> struct append_value_impl;
|
||||
|
||||
template<class L1 = mp_list_v<>, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
template<auto...> class L1, auto... T1,
|
||||
template<auto...> class L2, auto... T2,
|
||||
template<auto...> class L3, auto... T3,
|
||||
template<auto...> class L4, auto... T4,
|
||||
template<auto...> class L5, auto... T5,
|
||||
template<auto...> class L6, auto... T6,
|
||||
template<auto...> class L7, auto... T7,
|
||||
template<auto...> class L8, auto... T8,
|
||||
template<auto...> class L9, auto... T9,
|
||||
template<auto...> class L10, auto... T10,
|
||||
template<auto...> class L11, auto... T11>
|
||||
|
||||
struct append_value_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>,
|
||||
class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>,
|
||||
class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>,
|
||||
class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>,
|
||||
class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>,
|
||||
class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>,
|
||||
class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>,
|
||||
class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>,
|
||||
class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>,
|
||||
class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>,
|
||||
class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<>
|
||||
|
||||
> struct append_value_111_impl
|
||||
{
|
||||
using type = typename append_value_11_impl<
|
||||
|
||||
typename append_value_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
|
||||
|
||||
>::type;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
|
||||
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
|
||||
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
|
||||
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
|
||||
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
|
||||
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
|
||||
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
|
||||
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
|
||||
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
|
||||
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
|
||||
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
|
||||
class... Lr
|
||||
|
||||
> struct append_value_inf_impl
|
||||
{
|
||||
using prefix = typename append_value_111_impl<
|
||||
|
||||
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
|
||||
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
|
||||
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
|
||||
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
|
||||
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
|
||||
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
|
||||
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
|
||||
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
|
||||
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
|
||||
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
|
||||
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
|
||||
|
||||
>::type;
|
||||
|
||||
using type = typename append_value_impl<prefix, Lr...>::type;
|
||||
};
|
||||
|
||||
template<class... L> struct append_value_impl:
|
||||
mp_cond<
|
||||
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_value_inf_impl>,
|
||||
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_value_111_impl>,
|
||||
mp_true, mp_quote<append_value_11_impl>
|
||||
>::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
struct append_value_lists
|
||||
{
|
||||
template<class... L> using fn = typename append_value_impl<L...>::type;
|
||||
};
|
||||
|
||||
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<class... L> using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if<mp_list<L...>, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn<L...>;
|
||||
|
||||
#else
|
||||
|
||||
template<class... L> using mp_append = detail::append_type_lists::fn<L...>;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
||||
48
Chapter17/cib/libs/boost/mp11/detail/mp_copy_if.hpp
Normal file
48
Chapter17/cib/libs/boost/mp11/detail/mp_copy_if.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 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>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_copy_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_copy_if_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_copy_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
template<class U> struct _f { using type = mp_if<P<U>, mp_list<U>, mp_list<>>; };
|
||||
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||
#else
|
||||
template<class U> using _f = mp_if<P<U>, mp_list<U>, mp_list<>>;
|
||||
using type = mp_append<L<>, _f<T>...>;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_copy_if = typename detail::mp_copy_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_copy_if_q = mp_copy_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
||||
147
Chapter17/cib/libs/boost/mp11/detail/mp_count.hpp
Normal file
147
Chapter17/cib/libs/boost/mp11/detail/mp_count.hpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2016 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/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_count<L, V>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
constexpr std::size_t cx_plus()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
|
||||
{
|
||||
return static_cast<std::size_t>(t1) + cx_plus(t...);
|
||||
}
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
|
||||
constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
|
||||
{
|
||||
return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class L, class V> struct mp_count_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
||||
|
||||
template<class V, class... T> constexpr std::size_t cx_count()
|
||||
{
|
||||
constexpr bool a[] = { false, std::is_same<T, V>::value... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_count<V, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<mp_plus<std::is_same<T, V>...>::value>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class V> using mp_count = typename detail::mp_count_impl<L, V>::type;
|
||||
|
||||
// mp_count_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_count_if_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<template<class...> class P, class... T> constexpr std::size_t cx_count_if()
|
||||
{
|
||||
constexpr bool a[] = { false, static_cast<bool>( P<T>::value )... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
using type = mp_size_t<cx_count_if<P, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
using type = mp_size_t<cx_plus(mp_to_bool<P<T>>::value...)>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
|
||||
template<class T> struct _f { using type = mp_to_bool<P<T>>; };
|
||||
using type = mp_size_t<mp_plus<typename _f<T>::type...>::value>;
|
||||
|
||||
#else
|
||||
|
||||
using type = mp_size_t<mp_plus<mp_to_bool<P<T>>...>::value>;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||
119
Chapter17/cib/libs/boost/mp11/detail/mp_defer.hpp
Normal file
119
Chapter17/cib/libs/boost/mp11/detail/mp_defer.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2020, 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_if, mp_if_c
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool C, class T, class... E> struct mp_if_c_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class... E> struct mp_if_c_impl<true, T, E...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, class E> struct mp_if_c_impl<false, T, E>
|
||||
{
|
||||
using type = E;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
|
||||
template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
|
||||
|
||||
// mp_valid
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800
|
||||
|
||||
// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class...> using void_t = void;
|
||||
|
||||
template<class, template<class...> class F, class... T>
|
||||
struct mp_valid_impl: mp_false {};
|
||||
|
||||
template<template<class...> class F, class... T>
|
||||
struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
|
||||
|
||||
#else
|
||||
|
||||
// implementation by Bruno Dutra (by the name is_evaluable)
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_valid_impl
|
||||
{
|
||||
template<template<class...> class G, class = G<T...>> static mp_true check(int);
|
||||
template<template<class...> class> static mp_false check(...);
|
||||
|
||||
using type = decltype(check<F>(0));
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
|
||||
|
||||
#endif
|
||||
|
||||
template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
|
||||
|
||||
// mp_defer
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_defer_impl
|
||||
{
|
||||
using type = F<T...>;
|
||||
};
|
||||
|
||||
struct mp_no_type
|
||||
{
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
|
||||
{
|
||||
using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
||||
164
Chapter17/cib/libs/boost/mp11/detail/mp_fold.hpp
Normal file
164
Chapter17/cib/libs/boost/mp11/detail/mp_fold.hpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 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/detail/config.hpp>
|
||||
#include <boost/mp11/detail/mp_defer.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_fold<L, V, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class V, template<class...> class F> struct mp_fold_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_fold is not a list
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<template<class...> class L, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T...>, V, F>
|
||||
{
|
||||
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||
using type = V;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class V, template<class...> class F> struct mp_fold_impl<L<>, V, F>
|
||||
{
|
||||
using type = V;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q1
|
||||
{
|
||||
template<class T1>
|
||||
using fn = F<V, T1>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q2
|
||||
{
|
||||
template<class T1, class T2>
|
||||
using fn = F<F<V, T1>, T2>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q3
|
||||
{
|
||||
template<class T1, class T2, class T3>
|
||||
using fn = F<F<F<V, T1>, T2>, T3>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q4
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
using fn = F<F<F<F<V, T1>, T2>, T3>, T4>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q5
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5>
|
||||
using fn = F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q6
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
using fn = F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q7
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
||||
using fn = F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q8
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
||||
using fn = F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q9
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
|
||||
using fn = F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template<template<class...> class L, class T1, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1>, V, F>: mp_defer<mp_fold_Q1<V, F>::template fn, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2>, V, F>: mp_defer<mp_fold_Q2<V, F>::template fn, T1, T2>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3>, V, F>: mp_defer<mp_fold_Q3<V, F>::template fn, T1, T2, T3>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4>, V, F>: mp_defer<mp_fold_Q4<V, F>::template fn, T1, T2, T3, T4>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5>, V, F>: mp_defer<mp_fold_Q5<V, F>::template fn, T1, T2, T3, T4, T5>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6>, V, F>: mp_defer<mp_fold_Q6<V, F>::template fn, T1, T2, T3, T4, T5, T6>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7>, V, F>: mp_defer<mp_fold_Q7<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8>, V, F>: mp_defer<mp_fold_Q8<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9>, V, F>: mp_defer<mp_fold_Q9<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8, T9>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
|
||||
{
|
||||
using type = typename mp_fold_impl<L<T...>, F<F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
|
||||
template<class L, class V, class Q> using mp_fold_q = mp_fold<L, V, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
||||
50
Chapter17/cib/libs/boost/mp11/detail/mp_front.hpp
Normal file
50
Chapter17/cib/libs/boost/mp11/detail/mp_front.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 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/detail/mp_value.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A> struct mp_front_impl<L<A1, A...>>
|
||||
{
|
||||
using type = mp_value<A1>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
39
Chapter17/cib/libs/boost/mp11/detail/mp_is_list.hpp
Normal file
39
Chapter17/cib/libs/boost/mp11/detail/mp_is_list.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 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/integral.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_is_list<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_is_list_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_is_list_impl<L<T...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_is_list = typename detail::mp_is_list_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
||||
41
Chapter17/cib/libs/boost/mp11/detail/mp_is_value_list.hpp
Normal file
41
Chapter17/cib/libs/boost/mp11/detail/mp_is_value_list.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_is_value_list<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_is_value_list_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A> struct mp_is_value_list_impl<L<A...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_is_value_list = typename detail::mp_is_value_list_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
||||
24
Chapter17/cib/libs/boost/mp11/detail/mp_list.hpp
Normal file
24
Chapter17/cib/libs/boost/mp11/detail/mp_list.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2016 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
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_list<T...>
|
||||
template<class... T> struct mp_list
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||
27
Chapter17/cib/libs/boost/mp11/detail/mp_list_v.hpp
Normal file
27
Chapter17/cib/libs/boost/mp11/detail/mp_list_v.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
// mp_list_v<A...>
|
||||
template<auto... A> struct mp_list_v
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
||||
87
Chapter17/cib/libs/boost/mp11/detail/mp_map_find.hpp
Normal file
87
Chapter17/cib/libs/boost/mp11/detail/mp_map_find.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#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>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
// not exactly good practice, but...
|
||||
namespace std
|
||||
{
|
||||
template<class... _Types> class tuple;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_map_find
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<class T> using mpmf_wrap = mp_identity<T>;
|
||||
template<class T> using mpmf_unwrap = typename T::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mpmf_tuple {};
|
||||
|
||||
template<class T> struct mpmf_wrap_impl
|
||||
{
|
||||
using type = mp_identity<T>;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_wrap_impl< std::tuple<T...> >
|
||||
{
|
||||
using type = mp_identity< mpmf_tuple<T...> >;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_wrap = typename mpmf_wrap_impl<T>::type;
|
||||
|
||||
template<class T> struct mpmf_unwrap_impl
|
||||
{
|
||||
using type = typename T::type;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_unwrap_impl< mp_identity< mpmf_tuple<T...> > >
|
||||
{
|
||||
using type = std::tuple<T...>;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_unwrap = typename mpmf_unwrap_impl<T>::type;
|
||||
|
||||
#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
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<mpmf_wrap<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 type = mpmf_unwrap< decltype( f( static_cast<U*>(0) ) ) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||
51
Chapter17/cib/libs/boost/mp11/detail/mp_min_element.hpp
Normal file
51
Chapter17/cib/libs/boost/mp11/detail/mp_min_element.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 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/detail/mp_fold.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_min_element<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class P> struct select_min
|
||||
{
|
||||
template<class T1, class T2> using fn = mp_if<P<T1, T2>, T1, T2>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_min_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_min<P>>;
|
||||
template<class L, class Q> using mp_min_element_q = mp_min_element<L, Q::template fn>;
|
||||
|
||||
// mp_max_element<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class P> struct select_max
|
||||
{
|
||||
template<class T1, class T2> using fn = mp_if<P<T2, T1>, T1, T2>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_max_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_max<P>>;
|
||||
template<class L, class Q> using mp_max_element_q = mp_max_element<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
||||
84
Chapter17/cib/libs/boost/mp11/detail/mp_plus.hpp
Normal file
84
Chapter17/cib/libs/boost/mp11/detail/mp_plus.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_PLUS_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/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_plus
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 )
|
||||
|
||||
// msvc fails with parser stack overflow for large sizeof...(T)
|
||||
// clang exceeds -fbracket-depth, which defaults to 256
|
||||
|
||||
template<class... T> struct mp_plus_impl
|
||||
{
|
||||
static const auto _v = (T::value + ... + 0);
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mp_plus_impl;
|
||||
|
||||
template<> struct mp_plus_impl<>
|
||||
{
|
||||
using type = std::integral_constant<int, 0>;
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const
|
||||
decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
|
||||
_v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
||||
48
Chapter17/cib/libs/boost/mp11/detail/mp_remove_if.hpp
Normal file
48
Chapter17/cib/libs/boost/mp11/detail/mp_remove_if.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 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>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_remove_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_remove_if_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_remove_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
template<class U> struct _f { using type = mp_if<P<U>, mp_list<>, mp_list<U>>; };
|
||||
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||
#else
|
||||
template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
|
||||
using type = mp_append<L<>, _f<T>...>;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_remove_if = typename detail::mp_remove_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_remove_if_q = mp_remove_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
||||
54
Chapter17/cib/libs/boost/mp11/detail/mp_rename.hpp
Normal file
54
Chapter17/cib/libs/boost/mp11/detail/mp_rename.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 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/detail/mp_defer.hpp>
|
||||
#include <boost/mp11/detail/mp_value.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_rename<L, B>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class B> struct mp_rename_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class B> struct mp_rename_impl<L<T...>, B>: mp_defer<B, T...>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, template<class...> class B> struct mp_rename_impl<L<A...>, B>: mp_defer<B, mp_value<A>...>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<L, B>::type;
|
||||
|
||||
// mp_apply<F, L>
|
||||
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
|
||||
|
||||
// mp_apply_q<Q, L>
|
||||
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
25
Chapter17/cib/libs/boost/mp11/detail/mp_value.hpp
Normal file
25
Chapter17/cib/libs/boost/mp11/detail/mp_value.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
template<auto A> using mp_value = std::integral_constant<decltype(A), A>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
||||
32
Chapter17/cib/libs/boost/mp11/detail/mp_void.hpp
Normal file
32
Chapter17/cib/libs/boost/mp11/detail/mp_void.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 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
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_void<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_void_impl
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_void = typename detail::mp_void_impl<T...>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
||||
385
Chapter17/cib/libs/boost/mp11/detail/mp_with_index.hpp
Normal file
385
Chapter17/cib/libs/boost/mp11/detail/mp_with_index.hpp
Normal file
@@ -0,0 +1,385 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 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/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
||||
# define BOOST_MP11_CONSTEXPR14 constexpr
|
||||
#else
|
||||
# define BOOST_MP11_CONSTEXPR14
|
||||
#endif
|
||||
|
||||
#if defined( __GNUC__ ) || defined( __clang__ )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable();
|
||||
#elif defined( _MSC_VER )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false);
|
||||
#else
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<std::size_t N> struct mp_with_index_impl_
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
if( i < N / 2 )
|
||||
{
|
||||
return mp_with_index_impl_<N/2>::template call<K>( i, std::forward<F>(f) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return mp_with_index_impl_<N-N/2>::template call<K+N/2>( i - N/2, std::forward<F>(f) );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<0>
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<1>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t /*i*/, F && f )
|
||||
{
|
||||
return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<2>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<3>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<4>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<5>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<6>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<7>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<8>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<9>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<10>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<11>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<12>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<13>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<14>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<15>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<16>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<std::size_t N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||
{
|
||||
assert( i < N );
|
||||
return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
|
||||
}
|
||||
|
||||
template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||
{
|
||||
return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
|
||||
}
|
||||
|
||||
#undef BOOST_MP11_CONSTEXPR14
|
||||
#undef BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
||||
160
Chapter17/cib/libs/boost/mp11/detail/mpl_common.hpp
Normal file
160
Chapter17/cib/libs/boost/mp11/detail/mpl_common.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2019 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/list.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
struct forward_iterator_tag;
|
||||
|
||||
namespace aux
|
||||
{
|
||||
|
||||
struct mp11_tag {};
|
||||
|
||||
template<class L> struct mp11_iterator
|
||||
{
|
||||
using category = forward_iterator_tag;
|
||||
|
||||
using type = mp11::mp_first<L>;
|
||||
using next = mp11_iterator<mp11::mp_rest<L>>;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
// at
|
||||
|
||||
template< typename Tag > struct at_impl;
|
||||
|
||||
template<> struct at_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class I> struct apply
|
||||
{
|
||||
using type = mp11::mp_at<L, I>;
|
||||
};
|
||||
};
|
||||
|
||||
// back
|
||||
|
||||
template< typename Tag > struct back_impl;
|
||||
|
||||
template<> struct back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using N = mp11::mp_size<L>;
|
||||
using type = mp11::mp_at_c<L, N::value - 1>;
|
||||
};
|
||||
};
|
||||
|
||||
// begin
|
||||
|
||||
template< typename Tag > struct begin_impl;
|
||||
|
||||
template<> struct begin_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// clear
|
||||
|
||||
template< typename Tag > struct clear_impl;
|
||||
|
||||
template<> struct clear_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_clear<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// end
|
||||
|
||||
template< typename Tag > struct end_impl;
|
||||
|
||||
template<> struct end_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
|
||||
};
|
||||
};
|
||||
|
||||
// front
|
||||
|
||||
template< typename Tag > struct front_impl;
|
||||
|
||||
template<> struct front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// pop_front
|
||||
|
||||
template< typename Tag > struct pop_front_impl;
|
||||
|
||||
template<> struct pop_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_pop_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_back
|
||||
|
||||
template< typename Tag > struct push_back_impl;
|
||||
|
||||
template<> struct push_back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_back<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_front
|
||||
|
||||
template< typename Tag > struct push_front_impl;
|
||||
|
||||
template<> struct push_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_front<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// size
|
||||
|
||||
template< typename Tag > struct size_impl;
|
||||
|
||||
template<> struct size_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_size<L>;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||
222
Chapter17/cib/libs/boost/mp11/function.hpp
Normal file
222
Chapter17/cib/libs/boost/mp11/function.hpp
Normal file
@@ -0,0 +1,222 @@
|
||||
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||
#define BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 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/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_count.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/mp_min_element.hpp>
|
||||
#include <boost/mp11/detail/mp_void.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_void<T...>
|
||||
// in detail/mp_void.hpp
|
||||
|
||||
// mp_and<T...>
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_and_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<> struct mp_and_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_and_impl<T>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_and_impl<T1, T...>
|
||||
{
|
||||
using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class E = void> struct mp_and_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_all<T...>
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_false >::value == 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_or<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_or_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<> struct mp_or_impl<>
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<class T> struct mp_or_impl<T>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_or_impl<T1, T...>
|
||||
{
|
||||
using type = mp_eval_if< T1, T1, mp_or, T... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_any<T...>
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_true >::value != 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_same<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_same_impl;
|
||||
|
||||
template<> struct mp_same_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_same_impl<T1, T...>
|
||||
{
|
||||
using type = mp_bool< mp_count<mp_list<T...>, T1>::value == sizeof...(T) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type;
|
||||
|
||||
// mp_similar<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_similar_impl;
|
||||
|
||||
template<> struct mp_similar_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_similar_impl<T>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_similar_impl<T, T>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class T2> struct mp_similar_impl<T1, T2>
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T1, class... T2> struct mp_similar_impl<L<T1...>, L<T2...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...>
|
||||
{
|
||||
using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_similar = typename detail::mp_similar_impl<T...>::type;
|
||||
|
||||
#if BOOST_MP11_GCC
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
// mp_less<T1, T2>
|
||||
template<class T1, class T2> using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>;
|
||||
|
||||
#if BOOST_MP11_GCC
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// mp_min<T...>
|
||||
template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>;
|
||||
|
||||
// mp_max<T...>
|
||||
template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||
112
Chapter17/cib/libs/boost/mp11/integer_sequence.hpp
Normal file
112
Chapter17/cib/libs/boost/mp11/integer_sequence.hpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017, 2019 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/version.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__make_integer_seq)
|
||||
# define BOOST_MP11_HAS_MAKE_INTEGER_SEQ
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// integer_sequence
|
||||
template<class T, T... I> struct integer_sequence
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
template<class T, T N> using make_integer_sequence = __make_integer_seq<integer_sequence, T, N>;
|
||||
|
||||
#else
|
||||
|
||||
// detail::make_integer_sequence_impl
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// iseq_if_c
|
||||
template<bool C, class T, class E> struct iseq_if_c_impl;
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<true, T, E>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<false, T, E>
|
||||
{
|
||||
using type = E;
|
||||
};
|
||||
|
||||
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
|
||||
|
||||
// iseq_identity
|
||||
template<class T> struct iseq_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class S1, class S2> struct append_integer_sequence;
|
||||
|
||||
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
|
||||
{
|
||||
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl;
|
||||
|
||||
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;
|
||||
|
||||
using S1 = typename make_integer_sequence_impl<T, M>::type;
|
||||
using S2 = typename append_integer_sequence<S1, S1>::type;
|
||||
using S3 = typename make_integer_sequence_impl<T, R>::type;
|
||||
using S4 = typename append_integer_sequence<S2, S3>::type;
|
||||
|
||||
public:
|
||||
|
||||
using type = S4;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// make_integer_sequence
|
||||
template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
|
||||
|
||||
#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
// index_sequence
|
||||
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
|
||||
|
||||
// make_index_sequence
|
||||
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||
|
||||
// index_sequence_for
|
||||
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
42
Chapter17/cib/libs/boost/mp11/integral.hpp
Normal file
42
Chapter17/cib/libs/boost/mp11/integral.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
||||
#define BOOST_MP11_INTEGRAL_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/version.hpp>
|
||||
#include <boost/mp11/detail/mp_value.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_bool
|
||||
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
||||
|
||||
using mp_true = mp_bool<true>;
|
||||
using mp_false = mp_bool<false>;
|
||||
|
||||
// mp_to_bool
|
||||
template<class T> using mp_to_bool = mp_bool<static_cast<bool>( T::value )>;
|
||||
|
||||
// mp_not<T>
|
||||
template<class T> using mp_not = mp_bool< !T::value >;
|
||||
|
||||
// mp_int
|
||||
template<int I> using mp_int = std::integral_constant<int, I>;
|
||||
|
||||
// mp_size_t
|
||||
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
||||
472
Chapter17/cib/libs/boost/mp11/list.hpp
Normal file
472
Chapter17/cib/libs/boost/mp11/list.hpp
Normal file
@@ -0,0 +1,472 @@
|
||||
#ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 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/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list_v.hpp>
|
||||
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||
#include <boost/mp11/detail/mp_is_value_list.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_list<T...>
|
||||
// in detail/mp_list.hpp
|
||||
|
||||
// mp_list_c<T, I...>
|
||||
template<class T, T... I> using mp_list_c = mp_list<std::integral_constant<T, I>...>;
|
||||
|
||||
// mp_list_v<A...>
|
||||
// in detail/mp_list_v.hpp
|
||||
|
||||
// mp_is_list<L>
|
||||
// in detail/mp_is_list.hpp
|
||||
|
||||
// mp_is_value_list<L>
|
||||
// in detail/mp_is_value_list.hpp
|
||||
|
||||
// mp_size<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_size_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_size is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
|
||||
{
|
||||
using type = mp_size_t<sizeof...(T)>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A> struct mp_size_impl<L<A...>>
|
||||
{
|
||||
using type = mp_size_t<sizeof...(A)>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
|
||||
|
||||
// mp_empty<L>
|
||||
template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
|
||||
|
||||
// mp_assign<L1, L2>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L1, class L2> struct mp_assign_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the arguments to mp_assign aren't lists
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
|
||||
{
|
||||
using type = L1<U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L1, auto... A, template<class...> class L2, class... U> struct mp_assign_impl<L1<A...>, L2<U...>>
|
||||
{
|
||||
using type = L1<U::value...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<T...>, L2<B...>>
|
||||
{
|
||||
using type = L1<mp_value<B>...>;
|
||||
};
|
||||
|
||||
template<template<auto...> class L1, auto... A, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<A...>, L2<B...>>
|
||||
{
|
||||
using type = L1<B...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
|
||||
|
||||
// mp_clear<L>
|
||||
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
|
||||
|
||||
// mp_front<L>
|
||||
// in detail/mp_front.hpp
|
||||
|
||||
// mp_pop_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_pop_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_pop_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A> struct mp_pop_front_impl<L<A1, A...>>
|
||||
{
|
||||
using type = L<A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
|
||||
|
||||
// mp_first<L>
|
||||
template<class L> using mp_first = mp_front<L>;
|
||||
|
||||
// mp_rest<L>
|
||||
template<class L> using mp_rest = mp_pop_front<L>;
|
||||
|
||||
// mp_second<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
|
||||
{
|
||||
using type = T2;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A> struct mp_second_impl<L<A1, A2, A...>>
|
||||
{
|
||||
using type = mp_value<A2>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
|
||||
|
||||
// mp_third<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
|
||||
{
|
||||
using type = T3;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A> struct mp_third_impl<L<A1, A2, A3, A...>>
|
||||
{
|
||||
using type = mp_value<A3>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
|
||||
|
||||
// mp_push_front<L, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class... T> struct mp_push_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
|
||||
{
|
||||
using type = L<T..., U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, class... T> struct mp_push_front_impl<L<A...>, T...>
|
||||
{
|
||||
using type = L<T::value..., A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
|
||||
|
||||
// mp_push_back<L, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class... T> struct mp_push_back_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
|
||||
{
|
||||
using type = L<U..., T...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, class... T> struct mp_push_back_impl<L<A...>, T...>
|
||||
{
|
||||
using type = L<A..., T::value...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
|
||||
|
||||
// mp_rename<L, B>
|
||||
// mp_apply<F, L>
|
||||
// mp_apply_q<Q, L>
|
||||
// in detail/mp_rename.hpp
|
||||
|
||||
// mp_rename_v<L, B>
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<auto...> class B> struct mp_rename_v_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename_v is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<auto...> class B> struct mp_rename_v_impl<L<T...>, B>
|
||||
{
|
||||
using type = B<T::value...>;
|
||||
};
|
||||
|
||||
template<template<auto...> class L, auto... A, template<auto...> class B> struct mp_rename_v_impl<L<A...>, B>
|
||||
{
|
||||
using type = B<A...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<auto...> class B> using mp_rename_v = typename detail::mp_rename_v_impl<L, B>::type;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_replace_front<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
|
||||
{
|
||||
using type = L<T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A, class T> struct mp_replace_front_impl<L<A1, A...>, T>
|
||||
{
|
||||
using type = L<T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
|
||||
|
||||
// mp_replace_first<L, T>
|
||||
template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
|
||||
|
||||
// mp_replace_second<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
|
||||
{
|
||||
using type = L<U1, T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A, class T> struct mp_replace_second_impl<L<A1, A2, A...>, T>
|
||||
{
|
||||
using type = L<A1, T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
|
||||
|
||||
// mp_replace_third<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl<L<U1, U2, U3, U...>, T>
|
||||
{
|
||||
using type = L<U1, U2, T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, class T> struct mp_replace_third_impl<L<A1, A2, A3, A...>, T>
|
||||
{
|
||||
using type = L<A1, A2, T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
|
||||
|
||||
// mp_transform_front<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class... U, template<class...> class F> struct mp_transform_front_impl<L<U1, U...>, F>
|
||||
{
|
||||
using type = L<F<U1>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A, template<class...> class F> struct mp_transform_front_impl<L<A1, A...>, F>
|
||||
{
|
||||
using type = L<F<mp_value<A1>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_front = typename detail::mp_transform_front_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_front_q = mp_transform_front<L, Q::template fn>;
|
||||
|
||||
// mp_transform_first<L, F>
|
||||
template<class L, template<class...> class F> using mp_transform_first = typename detail::mp_transform_front_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_first_q = mp_transform_first<L, Q::template fn>;
|
||||
|
||||
// mp_transform_second<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class... U, template<class...> class F> struct mp_transform_second_impl<L<U1, U2, U...>, F>
|
||||
{
|
||||
using type = L<U1, F<U2>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A, template<class...> class F> struct mp_transform_second_impl<L<A1, A2, A...>, F>
|
||||
{
|
||||
using type = L<A1, F<mp_value<A2>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_second = typename detail::mp_transform_second_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_second_q = mp_transform_second<L, Q::template fn>;
|
||||
|
||||
// mp_transform_third<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class U3, class... U, template<class...> class F> struct mp_transform_third_impl<L<U1, U2, U3, U...>, F>
|
||||
{
|
||||
using type = L<U1, U2, F<U3>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, template<class...> class F> struct mp_transform_third_impl<L<A1, A2, A3, A...>, F>
|
||||
{
|
||||
using type = L<A1, A2, F<mp_value<A3>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_third = typename detail::mp_transform_third_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_third_q = mp_transform_third<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
||||
119
Chapter17/cib/libs/boost/mp11/map.hpp
Normal file
119
Chapter17/cib/libs/boost/mp11/map.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef BOOST_MP11_MAP_HPP_INCLUDED
|
||||
#define BOOST_MP11_MAP_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 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/detail/mp_map_find.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/set.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_map_contains<M, K>
|
||||
template<class M, class K> using mp_map_contains = mp_not<std::is_same<mp_map_find<M, K>, void>>;
|
||||
|
||||
// mp_map_insert<M, T>
|
||||
template<class M, class T> using mp_map_insert = mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;
|
||||
|
||||
// mp_map_replace<M, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class M, class T> struct mp_map_replace_impl;
|
||||
|
||||
template<template<class...> class M, class... U, class T> struct mp_map_replace_impl<M<U...>, T>
|
||||
{
|
||||
using K = mp_first<T>;
|
||||
|
||||
// mp_replace_if is inlined here using a struct _f because of msvc-14.0
|
||||
|
||||
template<class V> struct _f { using type = mp_if< std::is_same<mp_first<V>, K>, T, V >; };
|
||||
|
||||
using type = mp_if< mp_map_contains<M<U...>, K>, M<typename _f<U>::type...>, M<U..., T> >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class T> using mp_map_replace = typename detail::mp_map_replace_impl<M, T>::type;
|
||||
|
||||
// mp_map_update<M, T, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class M, class T, template<class...> class F> struct mp_map_update_impl
|
||||
{
|
||||
template<class U> using _f = std::is_same<mp_first<T>, mp_first<U>>;
|
||||
|
||||
// _f3<L<X, Y...>> -> L<X, F<X, Y...>>
|
||||
template<class L> using _f3 = mp_assign<L, mp_list<mp_first<L>, mp_rename<L, F> > >;
|
||||
|
||||
using type = mp_if< mp_map_contains<M, mp_first<T>>, mp_transform_if<_f, _f3, M>, mp_push_back<M, T> >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class T, template<class...> class F> using mp_map_update = typename detail::mp_map_update_impl<M, T, F>::type;
|
||||
template<class M, class T, class Q> using mp_map_update_q = mp_map_update<M, T, Q::template fn>;
|
||||
|
||||
// mp_map_erase<M, K>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class M, class K> struct mp_map_erase_impl
|
||||
{
|
||||
template<class T> using _f = std::is_same<mp_first<T>, K>;
|
||||
using type = mp_remove_if<M, _f>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class K> using mp_map_erase = typename detail::mp_map_erase_impl<M, K>::type;
|
||||
|
||||
// mp_map_keys<M>
|
||||
template<class M> using mp_map_keys = mp_transform<mp_first, M>;
|
||||
|
||||
// mp_is_map<M>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_is_map_element: mp_false
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_is_map_element<L<T1, T...>>: mp_true
|
||||
{
|
||||
};
|
||||
|
||||
template<class M> using mp_keys_are_set = mp_is_set<mp_map_keys<M>>;
|
||||
|
||||
template<class M> struct mp_is_map_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class M, class... T> struct mp_is_map_impl<M<T...>>
|
||||
{
|
||||
using type = mp_eval_if<mp_not<mp_all<mp_is_map_element<T>...>>, mp_false, mp_keys_are_set, M<T...>>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M> using mp_is_map = typename detail::mp_is_map_impl<M>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED
|
||||
14
Chapter17/cib/libs/boost/mp11/mpl.hpp
Normal file
14
Chapter17/cib/libs/boost/mp11/mpl.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef BOOST_MP11_MPL_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2019 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/mpl_list.hpp>
|
||||
#include <boost/mp11/mpl_tuple.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_HPP_INCLUDED
|
||||
28
Chapter17/cib/libs/boost/mp11/mpl_list.hpp
Normal file
28
Chapter17/cib/libs/boost/mp11/mpl_list.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2019 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/detail/mpl_common.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
template< typename Sequence > struct sequence_tag;
|
||||
|
||||
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||
29
Chapter17/cib/libs/boost/mp11/mpl_tuple.hpp
Normal file
29
Chapter17/cib/libs/boost/mp11/mpl_tuple.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2019 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/detail/mpl_common.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
template< typename Sequence > struct sequence_tag;
|
||||
|
||||
template<class... T> struct sequence_tag<std::tuple<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||
188
Chapter17/cib/libs/boost/mp11/set.hpp
Normal file
188
Chapter17/cib/libs/boost/mp11/set.hpp
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef BOOST_MP11_SET_HPP_INCLUDED
|
||||
#define BOOST_MP11_SET_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2019 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>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/mp_copy_if.hpp>
|
||||
#include <boost/mp11/detail/mp_remove_if.hpp>
|
||||
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_set_contains<S, V>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class V> struct mp_set_contains_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...> > >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
|
||||
|
||||
// mp_set_push_back<S, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class... T> struct mp_set_push_back_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
|
||||
{
|
||||
using type = L<U...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
|
||||
{
|
||||
using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
|
||||
using type = typename mp_set_push_back_impl<S, T...>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
|
||||
|
||||
// mp_set_push_front<S, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class... T> struct mp_set_push_front_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U> struct mp_set_push_front_impl<L<U...>>
|
||||
{
|
||||
using type = L<U...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1> struct mp_set_push_front_impl<L<U...>, T1>
|
||||
{
|
||||
using type = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<T1, U...>>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_front_impl<L<U...>, T1, T...>
|
||||
{
|
||||
using S = typename mp_set_push_front_impl<L<U...>, T...>::type;
|
||||
using type = typename mp_set_push_front_impl<S, T1>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
|
||||
|
||||
// mp_is_set<S>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S> struct mp_is_set_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_is_set_impl<L<T...>>
|
||||
{
|
||||
using type = mp_to_bool<std::is_same<mp_list<T...>, mp_set_push_back<mp_list<>, T...> > >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S> using mp_is_set = typename detail::mp_is_set_impl<S>::type;
|
||||
|
||||
// mp_set_union<L...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... L> struct mp_set_union_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_set_union_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_set_union_impl<L<T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_set_union_impl<L1<T1...>, L2<T2...>>
|
||||
{
|
||||
using type = mp_set_push_back<L1<T1...>, T2...>;
|
||||
};
|
||||
|
||||
template<class L1, class... L> using mp_set_union_ = typename mp_set_union_impl<L1, mp_append<mp_list<>, L...>>::type;
|
||||
|
||||
template<class L1, class L2, class L3, class... L> struct mp_set_union_impl<L1, L2, L3, L...>: mp_defer<mp_set_union_, L1, L2, L3, L...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... L> using mp_set_union = typename detail::mp_set_union_impl<L...>::type;
|
||||
|
||||
// mp_set_intersection<S...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... S> struct in_all_sets
|
||||
{
|
||||
template<class T> using fn = mp_all< mp_set_contains<S, T>... >;
|
||||
};
|
||||
|
||||
template<class L, class... S> using mp_set_intersection_ = mp_if< mp_all<mp_is_list<S>...>, mp_copy_if_q<L, detail::in_all_sets<S...>> >;
|
||||
|
||||
template<class... S> struct mp_set_intersection_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_set_intersection_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<class L, class... S> struct mp_set_intersection_impl<L, S...>: mp_defer<mp_set_intersection_, L, S...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... S> using mp_set_intersection = typename detail::mp_set_intersection_impl<S...>::type;
|
||||
|
||||
// mp_set_difference<L, S...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... S> struct in_any_set
|
||||
{
|
||||
template<class T> using fn = mp_any< mp_set_contains<S, T>... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... S> using mp_set_difference = mp_if< mp_all<mp_is_list<S>...>, mp_remove_if_q<L, detail::in_any_set<S...>> >;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
|
||||
183
Chapter17/cib/libs/boost/mp11/tuple.hpp
Normal file
183
Chapter17/cib/libs/boost/mp11/tuple.hpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
|
||||
#define BOOST_MP11_TUPLE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2020 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/integer_sequence.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp'
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// tuple_apply
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using std::get;
|
||||
|
||||
template<class F, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
|
||||
-> decltype( std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... ) )
|
||||
{
|
||||
return std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class F, class Tp,
|
||||
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
|
||||
-> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
|
||||
{
|
||||
return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
|
||||
}
|
||||
|
||||
// construct_from_tuple
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
|
||||
{
|
||||
return T( get<J>(std::forward<Tp>(tp))... );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T, class Tp,
|
||||
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
|
||||
BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp )
|
||||
{
|
||||
return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
|
||||
}
|
||||
|
||||
// tuple_for_each
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class Tp, std::size_t... J, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
|
||||
{
|
||||
using A = int[sizeof...(J)];
|
||||
return (void)A{ ((void)f(get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
|
||||
}
|
||||
|
||||
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
|
||||
{
|
||||
return std::forward<F>(f);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
|
||||
{
|
||||
using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
|
||||
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
|
||||
}
|
||||
|
||||
// tuple_transform
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// std::forward_as_tuple is not constexpr in C++11 or libstdc++ 5.x
|
||||
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_r( T&&... t ) -> std::tuple<T&&...>
|
||||
{
|
||||
return std::tuple<T&&...>( std::forward<T>( t )... );
|
||||
}
|
||||
|
||||
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_v( T&&... t ) -> std::tuple<T...>
|
||||
{
|
||||
return std::tuple<T...>( std::forward<T>( t )... );
|
||||
}
|
||||
|
||||
template<std::size_t J, class... Tp>
|
||||
BOOST_MP11_CONSTEXPR auto tp_extract( Tp&&... tp )
|
||||
-> decltype( tp_forward_r( get<J>( std::forward<Tp>( tp ) )... ) )
|
||||
{
|
||||
return tp_forward_r( get<J>( std::forward<Tp>( tp ) )... );
|
||||
}
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
template<class F, class... Tp, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp&&... tp )
|
||||
-> decltype( tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... ) )
|
||||
{
|
||||
return tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class F, class Tp1, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... );
|
||||
}
|
||||
|
||||
template<class F, class Tp1, class Tp2, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... );
|
||||
}
|
||||
|
||||
template<class F, class Tp1, class Tp2, class Tp3, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2, Tp3&& tp3 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... );
|
||||
}
|
||||
|
||||
#endif // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
template<class F, class Tp1, class... Tp,
|
||||
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp1>::type>::value>>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp1&& tp1, Tp&&... tp )
|
||||
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... ) )
|
||||
{
|
||||
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class F, class... Tp,
|
||||
class Z = mp_list<mp_size_t<std::tuple_size<typename std::remove_reference<Tp>::type>::value>...>,
|
||||
class E = mp_if<mp_apply<mp_same, Z>, mp_front<Z>>,
|
||||
class Seq = make_index_sequence<E::value>>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp&&... tp )
|
||||
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... ) )
|
||||
{
|
||||
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... );
|
||||
}
|
||||
|
||||
#endif // BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_TUPLE_HPP_INCLUDED
|
||||
169
Chapter17/cib/libs/boost/mp11/utility.hpp
Normal file
169
Chapter17/cib/libs/boost/mp11/utility.hpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
#define BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2020 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/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_fold.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/mp_defer.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_identity
|
||||
template<class T> struct mp_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
// mp_identity_t
|
||||
template<class T> using mp_identity_t = typename mp_identity<T>::type;
|
||||
|
||||
// mp_inherit
|
||||
template<class... T> struct mp_inherit: T... {};
|
||||
|
||||
// mp_if, mp_if_c
|
||||
// mp_valid
|
||||
// mp_defer
|
||||
// moved to detail/mp_defer.hpp
|
||||
|
||||
// mp_eval_if, mp_eval_if_c
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool C, class T, template<class...> class F, class... U> struct mp_eval_if_c_impl;
|
||||
|
||||
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<true, T, F, U...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<false, T, F, U...>: mp_defer<F, U...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl<C, T, F, U...>::type;
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, F, U...>::type;
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_q = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, Q::template fn, U...>::type;
|
||||
|
||||
// mp_eval_if_not
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if_not = mp_eval_if<mp_not<C>, T, F, U...>;
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_not_q = mp_eval_if<mp_not<C>, T, Q::template fn, U...>;
|
||||
|
||||
// mp_eval_or
|
||||
template<class T, template<class...> class F, class... U> using mp_eval_or = mp_eval_if_not<mp_valid<F, U...>, T, F, U...>;
|
||||
template<class T, class Q, class... U> using mp_eval_or_q = mp_eval_or<T, Q::template fn, U...>;
|
||||
|
||||
// mp_valid_and_true
|
||||
template<template<class...> class F, class... T> using mp_valid_and_true = mp_eval_or<mp_false, F, T...>;
|
||||
template<class Q, class... T> using mp_valid_and_true_q = mp_valid_and_true<Q::template fn, T...>;
|
||||
|
||||
// mp_cond
|
||||
|
||||
// so elegant; so doesn't work
|
||||
// template<class C, class T, class... E> using mp_cond = mp_eval_if<C, T, mp_cond, E...>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class C, class T, class... E> struct mp_cond_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class C, class T, class... E> using mp_cond = typename detail::mp_cond_impl<C, T, E...>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class C, class T, class... E> using mp_cond_ = mp_eval_if<C, T, mp_cond, E...>;
|
||||
|
||||
template<class C, class T, class... E> struct mp_cond_impl: mp_defer<mp_cond_, C, T, E...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_quote
|
||||
template<template<class...> class F> struct mp_quote
|
||||
{
|
||||
// the indirection through mp_defer works around the language inability
|
||||
// to expand T... into a fixed parameter list of an alias template
|
||||
|
||||
template<class... T> using fn = typename mp_defer<F, T...>::type;
|
||||
};
|
||||
|
||||
// mp_quote_trait
|
||||
template<template<class...> class F> struct mp_quote_trait
|
||||
{
|
||||
template<class... T> using fn = typename F<T...>::type;
|
||||
};
|
||||
|
||||
// mp_invoke_q
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class Q, class... T> struct mp_invoke_q_impl: mp_defer<Q::template fn, T...> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename detail::mp_invoke_q_impl<Q, T...>::type;
|
||||
|
||||
#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 )
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename mp_defer<Q::template fn, T...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename Q::template fn<T...>;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_not_fn<P>
|
||||
template<template<class...> class P> struct mp_not_fn
|
||||
{
|
||||
template<class... T> using fn = mp_not< mp_invoke_q<mp_quote<P>, T...> >;
|
||||
};
|
||||
|
||||
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
|
||||
|
||||
// mp_compose
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class Q> using mp_compose_helper = mp_list< mp_apply_q<Q, L> >;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
template<template<class...> class... F> struct mp_compose
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<mp_quote<F>...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<class... Q> struct mp_compose_q
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<Q...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
16
Chapter17/cib/libs/boost/mp11/version.hpp
Normal file
16
Chapter17/cib/libs/boost/mp11/version.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
#define BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 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
|
||||
|
||||
// Same format as BOOST_VERSION:
|
||||
// major * 100000 + minor * 100 + patch
|
||||
|
||||
#define BOOST_MP11_VERSION 108300
|
||||
|
||||
#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
15
Chapter17/cib/libs/cib/builder_meta.hpp
Normal file
15
Chapter17/cib/libs/cib/builder_meta.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
|
||||
namespace cib {
|
||||
template <typename T>
|
||||
concept builder_meta = requires {
|
||||
typename T::builder_t;
|
||||
typename T::interface_t;
|
||||
{ T::uninitialized() } -> std::same_as<typename T::interface_t>;
|
||||
};
|
||||
|
||||
template <builder_meta T> using builder_t = typename T::builder_t;
|
||||
template <builder_meta T> using interface_t = typename T::interface_t;
|
||||
} // namespace cib
|
||||
8
Chapter17/cib/libs/cib/built.hpp
Normal file
8
Chapter17/cib/libs/cib/built.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/builder_meta.hpp>
|
||||
|
||||
namespace cib {
|
||||
template <builder_meta ServiceMeta>
|
||||
constinit auto service = ServiceMeta::uninitialized();
|
||||
} // namespace cib
|
||||
131
Chapter17/cib/libs/cib/callback.hpp
Normal file
131
Chapter17/cib/libs/cib/callback.hpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/builder_meta.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
#include <stdx/panic.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
namespace callback {
|
||||
/**
|
||||
* Builder for simple callbacks.
|
||||
*
|
||||
* Components can add their own callback function to this builder to be
|
||||
* executed when the service is executed with the same function arguments.
|
||||
*
|
||||
* @tparam NumFuncs
|
||||
* The number of functions currently registered with this builder.
|
||||
*
|
||||
* @tparam ArgTypes
|
||||
* List of argument types that must be passed into the callback when it is
|
||||
* invoked.
|
||||
*
|
||||
* @see callback::service
|
||||
*/
|
||||
template <int NumFuncs = 0, typename... ArgTypes> struct builder {
|
||||
using func_ptr_t = void (*)(ArgTypes...);
|
||||
std::array<func_ptr_t, NumFuncs> funcs{};
|
||||
|
||||
/**
|
||||
* Add a function to be executed when the callback service is invoked.
|
||||
*
|
||||
* Do not call this function directly. The library will add functions
|
||||
* to service builders based on a project's cib::config and cib::extend
|
||||
* declarations.
|
||||
*
|
||||
* @return
|
||||
* A version of this callback builder with the addition of func.
|
||||
*
|
||||
* @see cib::extend
|
||||
* @see cib::nexus
|
||||
*/
|
||||
template <std::convertible_to<func_ptr_t>... Fs>
|
||||
[[nodiscard]] constexpr auto add(Fs &&...fs) const {
|
||||
builder<NumFuncs + sizeof...(Fs), ArgTypes...> cb;
|
||||
auto i = std::size_t{};
|
||||
while (i < NumFuncs) {
|
||||
cb.funcs[i] = funcs[i];
|
||||
++i;
|
||||
}
|
||||
((cb.funcs[i++] = std::forward<Fs>(fs)), ...);
|
||||
return cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and return a function pointer to the implemented callback
|
||||
* builder. Used by cib nexus to automatically build an initialized
|
||||
* builder.
|
||||
*
|
||||
* Do not call directly.
|
||||
*
|
||||
* @tparam BuilderValue
|
||||
* Struct that contains a "static constexpr auto value" field with the
|
||||
* initialized builder.
|
||||
*
|
||||
* @return
|
||||
* Function pointer to the implemented callback service.
|
||||
*/
|
||||
template <typename BuilderValue>
|
||||
[[nodiscard]] CONSTEVAL static auto build() {
|
||||
return run<BuilderValue>;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Runtime implementation of a callback service.
|
||||
*
|
||||
* Calls each registered function in an undefined order. The order
|
||||
* functions are called should not be depended upon and could
|
||||
* change from one release to the next.
|
||||
*
|
||||
* This function will be available from nexus::builder<...> or
|
||||
* cib::built<...>.
|
||||
*
|
||||
* @tparam BuilderValue
|
||||
* A type that contains a constexpr static value field with the
|
||||
* fully initialized callback builder.
|
||||
*
|
||||
* @param args
|
||||
* The arguments to be passed to every registered function.
|
||||
*
|
||||
* @see cib::nexus
|
||||
* @see cib::built
|
||||
*/
|
||||
template <typename BuilderValue> static void run(ArgTypes... args) {
|
||||
constexpr auto handler_builder = BuilderValue::value;
|
||||
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
(handler_builder.funcs[Is](args...), ...);
|
||||
}(std::make_index_sequence<NumFuncs>{});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extend this to create named callback services.
|
||||
*
|
||||
* Types that extend service can be used as unique names with
|
||||
* cib::exports and cib::extend.
|
||||
*
|
||||
* @tparam ArgTypes
|
||||
* The function arguments that must be passed into the callback
|
||||
* services implementation. any_t function registered with this
|
||||
* callback service must also have a compatible signature.
|
||||
*
|
||||
* @see cib::exports
|
||||
* @see cib::extend
|
||||
*/
|
||||
template <typename... ArgTypes> struct service {
|
||||
using builder_t = builder<0, ArgTypes...>;
|
||||
using interface_t = void (*)(ArgTypes...);
|
||||
|
||||
CONSTEVAL static auto uninitialized() -> interface_t {
|
||||
return [](ArgTypes...) {
|
||||
stdx::panic<
|
||||
"Attempting to run callback before it is initialized">();
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace callback
|
||||
45
Chapter17/cib/libs/cib/cib.hpp
Normal file
45
Chapter17/cib/libs/cib/cib.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer,
|
||||
* must be included in all copies of the Software, in whole or in part, and
|
||||
* all derivative works of the Software, unless such copies or derivative
|
||||
* works are solely in the form of machine-executable object code generated by
|
||||
* a source language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* cib - Compile-time Initialization and Build
|
||||
* ..~~VERSION~~..
|
||||
*
|
||||
* For the documentation and the latest version, see the official github repo:
|
||||
* https://github.com/intel/compile-time-init-build
|
||||
*/
|
||||
|
||||
#include <cib/builder_meta.hpp>
|
||||
#include <cib/built.hpp>
|
||||
#include <cib/callback.hpp>
|
||||
#include <cib/config.hpp>
|
||||
#include <cib/func_decl.hpp>
|
||||
#include <cib/nexus.hpp>
|
||||
#include <cib/top.hpp>
|
||||
#include <interrupt/manager.hpp>
|
||||
#include <log/log.hpp>
|
||||
74
Chapter17/cib/libs/cib/config.hpp
Normal file
74
Chapter17/cib/libs/cib/config.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/components.hpp>
|
||||
#include <cib/detail/config_details.hpp>
|
||||
#include <cib/detail/config_item.hpp>
|
||||
#include <cib/detail/constexpr_conditional.hpp>
|
||||
#include <cib/detail/exports.hpp>
|
||||
#include <cib/detail/extend.hpp>
|
||||
#include <cib/detail/runtime_conditional.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
|
||||
namespace cib {
|
||||
/**
|
||||
* Container for project and component configuration declarations.
|
||||
*
|
||||
* Each component or project type must contain a static constexpr "config"
|
||||
* field that contains the cib configuration for that component or project.
|
||||
* cib::config can be used to compose multiple configuration declarations.
|
||||
*
|
||||
* @see cib::components
|
||||
* @see cib::extend
|
||||
* @see cib::exports
|
||||
* @see cib::constexpr_condition
|
||||
* @see cib::runtime_condition
|
||||
*/
|
||||
template <typename... Configs>
|
||||
[[nodiscard]] CONSTEVAL auto config(Configs const &...configs) {
|
||||
return detail::config{configs...};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose one or more components into a project or larger component.
|
||||
*
|
||||
* @tparam Components
|
||||
* List of components to be added to the configuration.
|
||||
*/
|
||||
template <typename... Components>
|
||||
constexpr static detail::components<Components...> components{};
|
||||
|
||||
/**
|
||||
* Declare a list of services for use in the project.
|
||||
*
|
||||
* @tparam Services
|
||||
*/
|
||||
template <typename... Services>
|
||||
constexpr static detail::exports<Services...> exports{};
|
||||
|
||||
/**
|
||||
* Extend a service with new functionality.
|
||||
*
|
||||
* @tparam Service
|
||||
* Type name of the service to extend.
|
||||
*
|
||||
* @param args
|
||||
* Value arguments to be passed to the service's builder add function.
|
||||
*/
|
||||
template <typename Service, typename... Args>
|
||||
[[nodiscard]] CONSTEVAL auto extend(Args const &...args) {
|
||||
return detail::extend<Service, Args...>{args...};
|
||||
}
|
||||
|
||||
template <stdx::ct_string Name>
|
||||
constexpr auto constexpr_condition = []<typename P>(P) {
|
||||
static_assert(std::is_default_constructible_v<P>);
|
||||
return detail::constexpr_condition<Name, P>{};
|
||||
};
|
||||
|
||||
template <stdx::ct_string Name>
|
||||
constexpr auto runtime_condition = []<typename P>(P) {
|
||||
static_assert(std::is_default_constructible_v<P>);
|
||||
return detail::runtime_condition<Name, P>{};
|
||||
};
|
||||
} // namespace cib
|
||||
18
Chapter17/cib/libs/cib/detail/components.hpp
Normal file
18
Chapter17/cib/libs/cib/detail/components.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/config_item.hpp>
|
||||
|
||||
#include <stdx/tuple_algorithms.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
template <typename... Components>
|
||||
struct components : public detail::config_item {
|
||||
[[nodiscard]] constexpr auto extends_tuple() const {
|
||||
return stdx::tuple_cat(Components::config.extends_tuple()...);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto exports_tuple() const {
|
||||
return stdx::tuple_cat(Components::config.exports_tuple()...);
|
||||
}
|
||||
};
|
||||
} // namespace cib::detail
|
||||
36
Chapter17/cib/libs/cib/detail/config_details.hpp
Normal file
36
Chapter17/cib/libs/cib/detail/config_details.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/config_item.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
#include <stdx/tuple.hpp>
|
||||
#include <stdx/tuple_algorithms.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace cib::detail {
|
||||
template <auto Value>
|
||||
constexpr static auto as_constant_v =
|
||||
std::integral_constant<std::remove_cvref_t<decltype(Value)>, Value>{};
|
||||
|
||||
template <typename... ConfigTs> struct config : public detail::config_item {
|
||||
stdx::tuple<ConfigTs...> configs_tuple;
|
||||
|
||||
CONSTEVAL explicit config(ConfigTs const &...configs)
|
||||
: configs_tuple{configs...} {}
|
||||
|
||||
[[nodiscard]] constexpr auto extends_tuple() const {
|
||||
return configs_tuple.apply([&](auto const &...configs_pack) {
|
||||
return stdx::tuple_cat(configs_pack.extends_tuple()...);
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto exports_tuple() const {
|
||||
return configs_tuple.apply([&](auto const &...configs_pack) {
|
||||
return stdx::tuple_cat(configs_pack.exports_tuple()...);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Ts> config(Ts...) -> config<Ts...>;
|
||||
} // namespace cib::detail
|
||||
15
Chapter17/cib/libs/cib/detail/config_item.hpp
Normal file
15
Chapter17/cib/libs/cib/detail/config_item.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdx/tuple.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
struct config_item {
|
||||
[[nodiscard]] constexpr static auto extends_tuple() -> stdx::tuple<> {
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr static auto exports_tuple() -> stdx::tuple<> {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
} // namespace cib::detail
|
||||
51
Chapter17/cib/libs/cib/detail/constexpr_conditional.hpp
Normal file
51
Chapter17/cib/libs/cib/detail/constexpr_conditional.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/config_details.hpp>
|
||||
#include <cib/detail/config_item.hpp>
|
||||
#include <cib/detail/extend.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
#include <stdx/ct_format.hpp>
|
||||
#include <stdx/tuple.hpp>
|
||||
#include <stdx/tuple_algorithms.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
template <typename Cond, typename... Configs>
|
||||
struct constexpr_conditional : config_item {
|
||||
detail::config<Configs...> body;
|
||||
|
||||
CONSTEVAL explicit constexpr_conditional(Configs const &...configs)
|
||||
: body{configs...} {}
|
||||
|
||||
[[nodiscard]] constexpr auto extends_tuple() const {
|
||||
if constexpr (Cond{}) {
|
||||
return body.extends_tuple();
|
||||
} else {
|
||||
return stdx::tuple<>{};
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto exports_tuple() const {
|
||||
if constexpr (Cond{}) {
|
||||
return body.exports_tuple();
|
||||
} else {
|
||||
return stdx::tuple<>{};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <stdx::ct_string Name, typename... Ps> struct constexpr_condition {
|
||||
constexpr static auto predicates = stdx::make_tuple(Ps{}...);
|
||||
|
||||
constexpr static auto ct_name = Name;
|
||||
|
||||
template <typename... Configs>
|
||||
[[nodiscard]] CONSTEVAL auto operator()(Configs const &...configs) const {
|
||||
return detail::constexpr_conditional<constexpr_condition<Name, Ps...>,
|
||||
Configs...>{configs...};
|
||||
}
|
||||
|
||||
explicit constexpr operator bool() const { return (Ps{}() and ...); }
|
||||
};
|
||||
|
||||
} // namespace cib::detail
|
||||
25
Chapter17/cib/libs/cib/detail/exports.hpp
Normal file
25
Chapter17/cib/libs/cib/detail/exports.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/config_item.hpp>
|
||||
#include <cib/detail/extend.hpp>
|
||||
|
||||
#include <stdx/tuple.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
template <typename ServiceT, typename BuilderT> struct service_entry {
|
||||
using Service = ServiceT;
|
||||
BuilderT builder;
|
||||
};
|
||||
|
||||
template <typename... Services> struct exports : public detail::config_item {
|
||||
[[nodiscard]] constexpr auto
|
||||
extends_tuple() const -> stdx::tuple<extend<Services>...> {
|
||||
return {extend<Services>{}...};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto
|
||||
exports_tuple() const -> stdx::tuple<Services...> {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
} // namespace cib::detail
|
||||
22
Chapter17/cib/libs/cib/detail/extend.hpp
Normal file
22
Chapter17/cib/libs/cib/detail/extend.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/builder_meta.hpp>
|
||||
#include <cib/detail/config_item.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
#include <stdx/tuple.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
template <typename ServiceType, typename... Args>
|
||||
struct extend : public config_item {
|
||||
using service_type = ServiceType;
|
||||
constexpr static auto builder = cib::builder_t<service_type>{};
|
||||
stdx::tuple<Args...> args_tuple;
|
||||
|
||||
CONSTEVAL explicit extend(Args const &...args) : args_tuple{args...} {}
|
||||
|
||||
[[nodiscard]] constexpr auto extends_tuple() const -> stdx::tuple<extend> {
|
||||
return {*this};
|
||||
}
|
||||
};
|
||||
} // namespace cib::detail
|
||||
45
Chapter17/cib/libs/cib/detail/nexus_details.hpp
Normal file
45
Chapter17/cib/libs/cib/detail/nexus_details.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/exports.hpp>
|
||||
|
||||
#include <stdx/tuple.hpp>
|
||||
#include <stdx/tuple_algorithms.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace cib {
|
||||
template <typename T> using extract_service_tag = typename T::Service;
|
||||
|
||||
template <typename T>
|
||||
using get_service = typename std::remove_cvref_t<T>::service_type;
|
||||
|
||||
template <typename T>
|
||||
using get_service_from_tuple = typename std::remove_cvref_t<
|
||||
decltype(std::declval<T>()[stdx::index<0>])>::service_type;
|
||||
|
||||
template <typename Config>
|
||||
constexpr static auto initialized_builders = transform<extract_service_tag>(
|
||||
[](auto extensions) {
|
||||
using exports_tuple = decltype(Config::config.exports_tuple());
|
||||
using service = get_service_from_tuple<decltype(extensions)>;
|
||||
static_assert(stdx::contains_type<exports_tuple, service>);
|
||||
|
||||
constexpr auto initial_builder = extensions[stdx::index<0>].builder;
|
||||
|
||||
auto built_service = extensions.fold_right(
|
||||
initial_builder, [](auto extension, auto outer_builder) {
|
||||
return extension.args_tuple.apply(
|
||||
[&](auto... args) { return outer_builder.add(args...); });
|
||||
});
|
||||
|
||||
return detail::service_entry<service, decltype(built_service)>{
|
||||
built_service};
|
||||
},
|
||||
stdx::gather_by<get_service>(Config::config.extends_tuple()));
|
||||
|
||||
template <typename Config, typename Tag> struct initialized {
|
||||
constexpr static auto value =
|
||||
initialized_builders<Config>.get(stdx::tag<Tag>).builder;
|
||||
};
|
||||
} // namespace cib
|
||||
94
Chapter17/cib/libs/cib/detail/runtime_conditional.hpp
Normal file
94
Chapter17/cib/libs/cib/detail/runtime_conditional.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/detail/config_details.hpp>
|
||||
#include <cib/detail/config_item.hpp>
|
||||
#include <cib/detail/extend.hpp>
|
||||
|
||||
#include <stdx/compiler.hpp>
|
||||
#include <stdx/concepts.hpp>
|
||||
#include <stdx/ct_format.hpp>
|
||||
#include <stdx/tuple.hpp>
|
||||
#include <stdx/tuple_algorithms.hpp>
|
||||
|
||||
namespace cib::detail {
|
||||
namespace poison {
|
||||
template <typename... Ts>
|
||||
constexpr auto make_runtime_conditional(Ts &&...) = delete;
|
||||
}
|
||||
|
||||
template <typename Cond, typename... Configs>
|
||||
struct runtime_conditional : config_item {
|
||||
detail::config<Configs...> body;
|
||||
|
||||
CONSTEVAL explicit runtime_conditional(Configs const &...configs)
|
||||
: body{configs...} {}
|
||||
|
||||
[[nodiscard]] constexpr auto extends_tuple() const {
|
||||
return stdx::transform(
|
||||
[]<typename E>(E e) {
|
||||
auto args_tuple = stdx::transform(
|
||||
[]<typename Arg>(Arg) {
|
||||
using poison::make_runtime_conditional;
|
||||
return make_runtime_conditional(Cond{}, Arg{});
|
||||
},
|
||||
e.args_tuple);
|
||||
|
||||
return stdx::apply(
|
||||
[]<typename... Args>(Args...) {
|
||||
return extend<typename E::service_type, Args...>{
|
||||
Args{}...};
|
||||
},
|
||||
args_tuple);
|
||||
},
|
||||
body.extends_tuple());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto exports_tuple() const {
|
||||
return body.exports_tuple();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept runtime_predicate =
|
||||
std::default_initializable<T> and stdx::predicate<T>;
|
||||
|
||||
template <stdx::ct_string Name, runtime_predicate... Ps>
|
||||
struct runtime_condition {
|
||||
constexpr static auto predicates = stdx::make_tuple(Ps{}...);
|
||||
|
||||
constexpr static auto ct_name = Name;
|
||||
|
||||
template <typename... Configs>
|
||||
[[nodiscard]] CONSTEVAL auto operator()(Configs const &...configs) const {
|
||||
return detail::runtime_conditional<runtime_condition<Name, Ps...>,
|
||||
Configs...>{configs...};
|
||||
}
|
||||
|
||||
explicit operator bool() const { return (Ps{}() and ...); }
|
||||
};
|
||||
|
||||
template <stdx::ct_string LhsName, typename... LhsPs, stdx::ct_string RhsName,
|
||||
typename... RhsPs>
|
||||
[[nodiscard]] constexpr auto
|
||||
operator and(runtime_condition<LhsName, LhsPs...> const &lhs,
|
||||
runtime_condition<RhsName, RhsPs...> const &rhs) {
|
||||
if constexpr ((sizeof...(LhsPs) + sizeof...(RhsPs)) == 0) {
|
||||
return runtime_condition<"always">{};
|
||||
|
||||
} else if constexpr (sizeof...(LhsPs) == 0) {
|
||||
return rhs;
|
||||
|
||||
} else if constexpr (sizeof...(RhsPs) == 0) {
|
||||
return lhs;
|
||||
|
||||
} else {
|
||||
constexpr auto name =
|
||||
stdx::ct_format<"{} and {}">(CX_VALUE(LhsName), CX_VALUE(RhsName));
|
||||
|
||||
return runtime_condition<name.str.value, LhsPs..., RhsPs...>{};
|
||||
}
|
||||
}
|
||||
|
||||
using always_condition_t = runtime_condition<"always">;
|
||||
constexpr auto always_condition = always_condition_t{};
|
||||
} // namespace cib::detail
|
||||
12
Chapter17/cib/libs/cib/func_decl.hpp
Normal file
12
Chapter17/cib/libs/cib/func_decl.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdx/ct_string.hpp>
|
||||
|
||||
template <stdx::ct_string Name, typename... Args>
|
||||
extern auto cib_func(Args...) -> void;
|
||||
|
||||
namespace cib {
|
||||
template <stdx::ct_string Name, typename... Args>
|
||||
constexpr auto func_decl =
|
||||
[](Args... args) -> void { cib_func<Name>(args...); };
|
||||
} // namespace cib
|
||||
52
Chapter17/cib/libs/cib/nexus.hpp
Normal file
52
Chapter17/cib/libs/cib/nexus.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/built.hpp>
|
||||
#include <cib/detail/nexus_details.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace cib {
|
||||
/**
|
||||
* Combines all components in a single location so their features can
|
||||
* extend services.
|
||||
*
|
||||
* @tparam Config
|
||||
* Project configuration class that contains a single constexpr static
|
||||
* "config" field describing the cib::config
|
||||
*
|
||||
* @see cib::config
|
||||
*/
|
||||
|
||||
template <typename Config> struct nexus {
|
||||
// Workaround unfortunate bug in clang where it can't deduce "auto" sometimes
|
||||
#define CIB_BUILD_SERVICE \
|
||||
initialized<Config, Tag>::value.template build<initialized<Config, Tag>>()
|
||||
|
||||
template <typename Tag>
|
||||
constexpr static decltype(CIB_BUILD_SERVICE) service = CIB_BUILD_SERVICE;
|
||||
#undef CIB_BUILD_SERVICE
|
||||
|
||||
static void init() {
|
||||
auto const service = []<typename T> {
|
||||
using from_t = std::remove_cvref_t<decltype(nexus::service<T>)>;
|
||||
using to_t = std::remove_cvref_t<decltype(cib::service<T>)>;
|
||||
|
||||
auto &service_impl = nexus::service<T>;
|
||||
if constexpr (std::is_convertible_v<from_t, to_t>) {
|
||||
cib::service<T> = service_impl;
|
||||
} else {
|
||||
if constexpr (std::is_pointer_v<from_t>) {
|
||||
cib::service<T> = service_impl;
|
||||
} else {
|
||||
cib::service<T> = &service_impl;
|
||||
}
|
||||
}
|
||||
};
|
||||
initialized_builders<Config>.apply([&]<typename... Ts>(Ts const &...) {
|
||||
(service.template
|
||||
operator()<std::remove_cvref_t<typename Ts::Service>>(),
|
||||
...);
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace cib
|
||||
72
Chapter17/cib/libs/cib/top.hpp
Normal file
72
Chapter17/cib/libs/cib/top.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cib/config.hpp>
|
||||
#include <cib/nexus.hpp>
|
||||
#include <flow/flow.hpp>
|
||||
|
||||
namespace cib {
|
||||
/**
|
||||
* Executed immediately after the C++ runtime is stable. This should be
|
||||
* used to initialize essential services like logging and potentially
|
||||
* configure the host system the project is running on.
|
||||
*/
|
||||
class EarlyRuntimeInit : public flow::service<> {};
|
||||
|
||||
/**
|
||||
* Executed once after essential services like logging are initialized.
|
||||
* This can be used for general component runtime initialization.
|
||||
*/
|
||||
class RuntimeInit : public flow::service<> {};
|
||||
|
||||
/**
|
||||
* Executed after all runtime initialization is completed. This is where
|
||||
* the project can start doing its job including enabling interrupts and/or
|
||||
* starting threads if applicable and be ready to start accepting and
|
||||
* processing external events.
|
||||
*/
|
||||
class RuntimeStart : public flow::service<> {};
|
||||
|
||||
/**
|
||||
* Executed repeated in an infinite loop after initialization and
|
||||
* RuntimeStart flows have completed.
|
||||
*/
|
||||
class MainLoop : public flow::service<> {};
|
||||
|
||||
/**
|
||||
* The top object for cib framework. Call 'main' to execute the project.
|
||||
*/
|
||||
template <typename ProjectConfig> class top {
|
||||
private:
|
||||
struct component {
|
||||
constexpr static auto config = cib::config(
|
||||
cib::exports<EarlyRuntimeInit, RuntimeInit, RuntimeStart, MainLoop>,
|
||||
cib::components<ProjectConfig>);
|
||||
};
|
||||
|
||||
constexpr static cib::nexus<component> my_nexus{};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Main entry point to cib top.
|
||||
*/
|
||||
[[noreturn]] inline void main() {
|
||||
my_nexus.init();
|
||||
flow::run<EarlyRuntimeInit>();
|
||||
|
||||
CIB_INFO("cib::top::init() - RuntimeInit");
|
||||
flow::run<RuntimeInit>();
|
||||
|
||||
CIB_INFO("cib::top::init() - RuntimeStart");
|
||||
flow::run<RuntimeStart>();
|
||||
|
||||
while (true) {
|
||||
flow::run<MainLoop>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ServiceMeta>
|
||||
constexpr static auto get_service() -> auto & {
|
||||
return my_nexus.template service<ServiceMeta>;
|
||||
}
|
||||
};
|
||||
} // namespace cib
|
||||
196
Chapter17/cib/libs/conc/atomic.hpp
Normal file
196
Chapter17/cib/libs/conc/atomic.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#pragma once
|
||||
|
||||
#include <conc/concepts.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
#define CPP20(...) __VA_ARGS__
|
||||
#else
|
||||
#define CPP20(...)
|
||||
#endif
|
||||
|
||||
namespace atomic {
|
||||
namespace detail {
|
||||
struct standard_policy {
|
||||
static_assert(static_cast<int>(std::memory_order_relaxed) ==
|
||||
__ATOMIC_RELAXED);
|
||||
static_assert(static_cast<int>(std::memory_order_acquire) ==
|
||||
__ATOMIC_ACQUIRE);
|
||||
static_assert(static_cast<int>(std::memory_order_release) ==
|
||||
__ATOMIC_RELEASE);
|
||||
static_assert(static_cast<int>(std::memory_order_seq_cst) ==
|
||||
__ATOMIC_SEQ_CST);
|
||||
static_assert(static_cast<int>(std::memory_order_acq_rel) ==
|
||||
__ATOMIC_ACQ_REL);
|
||||
static_assert(static_cast<int>(std::memory_order_consume) ==
|
||||
__ATOMIC_CONSUME);
|
||||
|
||||
template <typename T>
|
||||
static auto load(T const &t,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
T ret{};
|
||||
__atomic_load(std::addressof(t), std::addressof(ret),
|
||||
static_cast<int>(mo));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
store(T &t, T &value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> void {
|
||||
__atomic_store(std::addressof(t), std::addressof(value),
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
exchange(T &t, T &value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
T ret{};
|
||||
__atomic_exchange(std::addressof(t), std::addressof(value),
|
||||
std::addressof(ret), static_cast<int>(mo));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
fetch_add(T &t, T value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
return __atomic_fetch_add(std::addressof(t), value,
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
fetch_sub(T &t, T value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
return __atomic_fetch_sub(std::addressof(t), value,
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
fetch_and(T &t, T value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
return __atomic_fetch_and(std::addressof(t), value,
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
fetch_or(T &t, T value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
return __atomic_fetch_or(std::addressof(t), value,
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static auto
|
||||
fetch_xor(T &t, T value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
return __atomic_fetch_xor(std::addressof(t), value,
|
||||
static_cast<int>(mo));
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename...> inline auto injected_policy = detail::standard_policy{};
|
||||
|
||||
template <typename... DummyArgs, typename T>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
[[nodiscard]] auto load(T const &t,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(load_store_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.load(t, mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto store(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> void {
|
||||
CPP20(load_store_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
auto v = static_cast<T>(value);
|
||||
p.store(t, v, mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
[[nodiscard]] auto exchange(
|
||||
T &t, U value, std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(exchange_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
auto v = static_cast<T>(value);
|
||||
return p.exchange(t, v, mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto fetch_add(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(add_sub_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.fetch_add(t, static_cast<T>(value), mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto fetch_sub(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(add_sub_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.fetch_sub(t, static_cast<T>(value), mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto fetch_and(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(bitwise_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.fetch_and(t, static_cast<T>(value), mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto fetch_or(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(bitwise_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.fetch_or(t, static_cast<T>(value), mo);
|
||||
}
|
||||
|
||||
template <typename... DummyArgs, typename T, typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
CPP20(requires(sizeof...(DummyArgs) == 0))
|
||||
auto fetch_xor(T &t, U value,
|
||||
std::memory_order mo = std::memory_order_seq_cst) -> T {
|
||||
CPP20(bitwise_policy)
|
||||
auto &p = injected_policy<DummyArgs...>;
|
||||
return p.fetch_xor(t, static_cast<T>(value), mo);
|
||||
}
|
||||
|
||||
template <typename T> struct atomic_type {
|
||||
using type = T;
|
||||
};
|
||||
template <typename T> using atomic_type_t = typename atomic_type<T>::type;
|
||||
|
||||
template <typename T>
|
||||
constexpr inline auto alignment_of = alignof(std::atomic<atomic_type_t<T>>);
|
||||
} // namespace atomic
|
||||
|
||||
#undef CPP20
|
||||
|
||||
#ifdef ATOMIC_CFG
|
||||
#include ATOMIC_CFG
|
||||
#endif
|
||||
56
Chapter17/cib/libs/conc/concepts.hpp
Normal file
56
Chapter17/cib/libs/conc/concepts.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
|
||||
#include <atomic>
|
||||
#include <concepts>
|
||||
|
||||
namespace conc {
|
||||
template <typename T>
|
||||
concept policy = requires(auto (*f)()->int &&, auto (*pred)()->bool) {
|
||||
{ T::call_in_critical_section(f) } -> std::same_as<int &&>;
|
||||
{ T::call_in_critical_section(f, pred) } -> std::same_as<int &&>;
|
||||
};
|
||||
} // namespace conc
|
||||
|
||||
namespace atomic {
|
||||
template <typename T>
|
||||
concept load_store_policy = requires(int &a, int value, std::memory_order mo) {
|
||||
{ T::load(a) } -> std::same_as<int>;
|
||||
{ T::load(a, mo) } -> std::same_as<int>;
|
||||
{ T::store(a, value) } -> std::same_as<void>;
|
||||
{ T::store(a, value, mo) } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept exchange_policy =
|
||||
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
|
||||
{ T::exchange(a, value) } -> std::same_as<int>;
|
||||
{ T::exchange(a, value, mo) } -> std::same_as<int>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept add_sub_policy =
|
||||
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
|
||||
{ T::fetch_add(a, value) } -> std::same_as<int>;
|
||||
{ T::fetch_add(a, value, mo) } -> std::same_as<int>;
|
||||
{ T::fetch_sub(a, value) } -> std::same_as<int>;
|
||||
{ T::fetch_sub(a, value, mo) } -> std::same_as<int>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept bitwise_policy =
|
||||
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
|
||||
{ T::fetch_and(a, value) } -> std::same_as<int>;
|
||||
{ T::fetch_and(a, value, mo) } -> std::same_as<int>;
|
||||
{ T::fetch_or(a, value) } -> std::same_as<int>;
|
||||
{ T::fetch_or(a, value, mo) } -> std::same_as<int>;
|
||||
{ T::fetch_xor(a, value) } -> std::same_as<int>;
|
||||
{ T::fetch_xor(a, value, mo) } -> std::same_as<int>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept policy = exchange_policy<T> and add_sub_policy<T> and bitwise_policy<T>;
|
||||
} // namespace atomic
|
||||
|
||||
#endif
|
||||
67
Chapter17/cib/libs/conc/concurrency.hpp
Normal file
67
Chapter17/cib/libs/conc/concurrency.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMULATE_FREESTANDING
|
||||
#define HAS_MUTEX 0
|
||||
#else
|
||||
#define HAS_MUTEX __has_include(<mutex>)
|
||||
#endif
|
||||
|
||||
#include <conc/concepts.hpp>
|
||||
|
||||
#if HAS_MUTEX
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
#include <concepts>
|
||||
#include <utility>
|
||||
|
||||
namespace conc {
|
||||
namespace detail {
|
||||
template <typename...> constexpr auto always_false_v = false;
|
||||
|
||||
#if HAS_MUTEX
|
||||
template <typename Mutex = std::mutex> class standard_policy {
|
||||
template <typename> static inline Mutex m{};
|
||||
|
||||
public:
|
||||
template <typename Uniq = void, std::invocable F, std::predicate... Pred>
|
||||
requires(sizeof...(Pred) < 2)
|
||||
static auto call_in_critical_section(F &&f, Pred &&...pred)
|
||||
-> decltype(std::forward<F>(f)()) {
|
||||
while (true) {
|
||||
[[maybe_unused]] std::lock_guard l{m<Uniq>};
|
||||
if ((... and pred())) {
|
||||
return std::forward<F>(f)();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#else
|
||||
template <typename = void> struct standard_policy {
|
||||
template <typename = void, std::invocable F, std::predicate... Pred>
|
||||
requires(sizeof...(Pred) < 2)
|
||||
static auto call_in_critical_section(F &&f, Pred &&...)
|
||||
-> decltype(std::forward<F>(f)()) {
|
||||
static_assert(always_false_v<F, Pred...>,
|
||||
"No standard concurrency policy defined: inject a policy "
|
||||
"by specializing conc::injected_policy<>");
|
||||
return std::forward<F>(f)();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
} // namespace detail
|
||||
|
||||
template <typename...> inline auto injected_policy = detail::standard_policy{};
|
||||
|
||||
template <typename Uniq = decltype([] {}), typename... DummyArgs,
|
||||
std::invocable F, std::predicate... Pred>
|
||||
requires(sizeof...(DummyArgs) == 0 and sizeof...(Pred) < 2)
|
||||
auto call_in_critical_section(F &&f, Pred &&...pred)
|
||||
-> decltype(std::forward<F>(f)()) {
|
||||
policy auto &p = injected_policy<DummyArgs...>;
|
||||
return p.template call_in_critical_section<Uniq>(
|
||||
std::forward<F>(f), std::forward<Pred>(pred)...);
|
||||
}
|
||||
} // namespace conc
|
||||
|
||||
#undef HAS_MUTEX
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user