rename chapters
This commit is contained in:
9
Chapter17/cib/.clang-format
Normal file
9
Chapter17/cib/.clang-format
Normal file
@@ -0,0 +1,9 @@
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
BreakBeforeBraces: Allman
|
||||
ColumnLimit: 80
|
||||
SpaceBeforeParens: Never
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
27
Chapter17/cib/.clang-tidy
Normal file
27
Chapter17/cib/.clang-tidy
Normal file
@@ -0,0 +1,27 @@
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
misc-*,
|
||||
clang-analyzer-*,
|
||||
modernize-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
performance-*,
|
||||
-performance-no-int-to-ptr,
|
||||
portability-*,
|
||||
readability-*,
|
||||
-readability-identifier-length
|
||||
readability-identifier-naming
|
||||
|
||||
CheckOptions:
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.ClassCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.StructCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.MethodCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||
- { key: readability-identifier-naming.ConstexprVariablePrefix, value: c_ }
|
||||
|
||||
ExtraArgs:
|
||||
- -std=c++20
|
||||
162
Chapter17/cib/CMakeLists.txt
Normal file
162
Chapter17/cib/CMakeLists.txt
Normal file
@@ -0,0 +1,162 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
|
||||
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
|
||||
set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
|
||||
set(CMAKE_ASM_COMPILER "arm-none-eabi-gcc")
|
||||
set(CMAKE_OBJCOPY "arm-none-eabi-objcopy")
|
||||
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.cpp" CACHE STRING "main file")
|
||||
list(APPEND LIB_SPECS "-specs=nosys.specs")
|
||||
list(APPEND LIB_SPECS "-specs=nano.specs")
|
||||
|
||||
set(EXCEPTIONS_FLAGS "-fno-exceptions -fno-rtti")
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
endif(CCACHE_FOUND)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
set(CDEFS "-DUSE_HAL_DRIVER -DSTM32F072xB")
|
||||
set(MCU "-mcpu=cortex-m0 -mthumb")
|
||||
set(COMMON_FLAGS "${MCU} ${CDEFS} -fdata-sections -ffunction-sections -Wno-address-of-packed-member -Wall -Wextra -Wno-unused-parameter")
|
||||
set(CMAKE_C_FLAGS "${COMMON_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${COMMON_FLAGS} -Wno-register ${EXCEPTIONS_FLAGS} -fno-threadsafe-statics")
|
||||
set(CMAKE_ASM_FLAGS "${COMMON_FLAGS} -x assembler-with-cpp")
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -gdwarf-2 -Og")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -gdwarf-2 -Og")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -flto")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -flto")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -flto")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -flto")
|
||||
|
||||
if(CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
# This dreadful mess is to communicate to clang-tidy the C++ system includes.
|
||||
# It seems that CMake doesn't support using its own compile_commands.json
|
||||
# database, and that clang-tidy doesn't pick up non-default system headers.
|
||||
execute_process(
|
||||
COMMAND
|
||||
bash -c
|
||||
"${CMAKE_CXX_COMPILER} -x c++ -Wp,-v /dev/null 2>&1 > /dev/null | grep '^ /' | grep -w 'c++'"
|
||||
OUTPUT_VARIABLE COMPILER_HEADERS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE "[ \n\t]+" ";" INCLUDE_COMPILER_HEADERS
|
||||
${COMPILER_HEADERS})
|
||||
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${INCLUDE_COMPILER_HEADERS})
|
||||
message(STATUS "${CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES}")
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
bash -c
|
||||
"${CMAKE_C_COMPILER} -x c -Wp,-v /dev/null 2>&1 > /dev/null | grep '^ /' "
|
||||
OUTPUT_VARIABLE COMPILER_HEADERS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE "[ \n\t]+" ";" INCLUDE_COMPILER_HEADERS
|
||||
${COMPILER_HEADERS})
|
||||
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES ${INCLUDE_COMPILER_HEADERS})
|
||||
message(STATUS "${CMAKE_C_STANDARD_INCLUDE_DIRECTORIES}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
|
||||
"${CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES} ${CMAKE_C_STANDARD_INCLUDE_DIRECTORIES}"
|
||||
)
|
||||
endif()
|
||||
|
||||
project(bare VERSION 1.0.6)
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# global include directories
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/platform/inc
|
||||
${CMAKE_SOURCE_DIR}/platform/CMSIS/Device/ST/STM32F0xx/Include
|
||||
${CMAKE_SOURCE_DIR}/platform/CMSIS/Include
|
||||
${CMAKE_SOURCE_DIR}/platform/STM32F0xx_HAL_Driver/Inc
|
||||
${CMAKE_SOURCE_DIR}/app/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/uart/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/inc
|
||||
${CMAKE_SOURCE_DIR}/hal/adc/inc
|
||||
${CMAKE_SOURCE_DIR}/cstdlib_support
|
||||
${CMAKE_SOURCE_DIR}/util/inc
|
||||
${CMAKE_SOURCE_DIR}/libs
|
||||
)
|
||||
|
||||
set(EXECUTABLE ${PROJECT_NAME}.elf)
|
||||
|
||||
add_executable(
|
||||
${EXECUTABLE}
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_adc.c
|
||||
platform/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_adc_ex.c
|
||||
platform/startup_stm32f072xb.s
|
||||
platform/src/stm32f0xx_hal_msp.c
|
||||
platform/src/stm32f0xx_it.c
|
||||
platform/src/system_stm32f0xx.c
|
||||
hal/adc/src/adc_stm32.cpp
|
||||
cstdlib_support/retarget.cpp
|
||||
util/src/units.cpp
|
||||
${MAIN_CPP_PATH}/${MAIN_CPP_FILE_NAME}
|
||||
)
|
||||
|
||||
target_link_libraries(${EXECUTABLE} PUBLIC)
|
||||
|
||||
target_compile_definitions(${EXECUTABLE} PUBLIC "-DSIMULATE_FREESTANDING")
|
||||
|
||||
target_include_directories(${EXECUTABLE} PUBLIC ${PROJECT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR})
|
||||
|
||||
set_target_properties(${EXECUTABLE} PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
target_link_options(
|
||||
${EXECUTABLE}
|
||||
PUBLIC
|
||||
-T${CMAKE_SOURCE_DIR}/platform/STM32F072C8Tx_FLASH.ld
|
||||
-mcpu=cortex-m0
|
||||
-mthumb
|
||||
${LIB_SPECS}
|
||||
-lnosys
|
||||
-u
|
||||
_printf_float
|
||||
-lc
|
||||
-lm
|
||||
-Wl,--no-warn-rwx-segments
|
||||
-Wl,-Map=${PROJECT_NAME}.map,--cref
|
||||
-Wl,--gc-sections)
|
||||
|
||||
add_subdirectory(libs/etl)
|
||||
target_link_libraries(${EXECUTABLE} PRIVATE etl::etl)
|
||||
|
||||
# Print executable size
|
||||
add_custom_command(
|
||||
TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND arm-none-eabi-size ${EXECUTABLE})
|
||||
|
||||
# Create hex file
|
||||
add_custom_command(
|
||||
TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND arm-none-eabi-objcopy -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
|
||||
COMMAND arm-none-eabi-objcopy -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)
|
||||
|
||||
# Run elf in Renode
|
||||
add_custom_target(
|
||||
run_in_renode
|
||||
COMMAND ${RENODE} --console --disable-xwt ${CMAKE_SOURCE_DIR}/renode_scripts/stm32f072.resc -e start
|
||||
DEPENDS ${PROJECT_NAME}.elf)
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
81
Chapter17/cib/cstdlib_support/retarget.cpp
Normal file
81
Chapter17/cib/cstdlib_support/retarget.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <retarget.hpp>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <span>
|
||||
|
||||
namespace
|
||||
{
|
||||
hal::uart *uart_stdio;
|
||||
};
|
||||
|
||||
void retarget::set_stdio_uart(hal::uart *uart)
|
||||
{
|
||||
uart_stdio = uart;
|
||||
|
||||
/* Disable I/O buffering for STDOUT stream, so that
|
||||
* chars are sent out as soon as they are printed. */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
||||
extern "C" int _write(int fd, char * ptr, int len)
|
||||
{
|
||||
if(fd == STDOUT_FILENO || fd == STDERR_FILENO)
|
||||
{
|
||||
uart_stdio->write(std::span<const char>(ptr, len));
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
extern "C" int _isatty(int fd)
|
||||
{
|
||||
if(fd >= STDIN_FILENO && fd <= STDERR_FILENO)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
errno = EBADF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int _close(int fd)
|
||||
{
|
||||
if(fd >= STDIN_FILENO && fd <= STDERR_FILENO)
|
||||
return 0;
|
||||
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _lseek(int fd, int ptr, int dir)
|
||||
{
|
||||
(void)fd;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _read(int fd, char *ptr, int len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fstat(int fd, struct stat *st)
|
||||
{
|
||||
if(fd >= STDIN_FILENO && fd <= STDERR_FILENO)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = EBADF;
|
||||
return 0;
|
||||
}
|
||||
10
Chapter17/cib/cstdlib_support/retarget.hpp
Normal file
10
Chapter17/cib/cstdlib_support/retarget.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <uart.hpp>
|
||||
|
||||
namespace retarget
|
||||
{
|
||||
|
||||
void set_stdio_uart(hal::uart *uart);
|
||||
|
||||
};
|
||||
18
Chapter17/cib/hal/adc/inc/adc.hpp
Normal file
18
Chapter17/cib/hal/adc/inc/adc.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
|
||||
#include <units.hpp>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
class adc {
|
||||
public:
|
||||
enum class error {
|
||||
timeout
|
||||
};
|
||||
|
||||
virtual void init() = 0;
|
||||
virtual std::expected<units::voltage, adc::error> get_reading() = 0;
|
||||
};
|
||||
};
|
||||
22
Chapter17/cib/hal/adc/inc/adc_stm32.hpp
Normal file
22
Chapter17/cib/hal/adc/inc/adc_stm32.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <adc.hpp>
|
||||
#include <units.hpp>
|
||||
|
||||
#include <stm32f0xx_hal.h>
|
||||
#include <stm32f072xb.h>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
|
||||
class adc_stm32 : public adc{
|
||||
public:
|
||||
adc_stm32(units::voltage ref_voltage) : ref_voltage_(ref_voltage) {}
|
||||
|
||||
void init() override;
|
||||
std::expected<units::voltage, adc::error> get_reading() override;
|
||||
private:
|
||||
ADC_HandleTypeDef adc_handle_;
|
||||
units::voltage ref_voltage_;
|
||||
};
|
||||
};
|
||||
47
Chapter17/cib/hal/adc/src/adc_stm32.cpp
Normal file
47
Chapter17/cib/hal/adc/src/adc_stm32.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <adc_stm32.hpp>
|
||||
|
||||
void hal::adc_stm32::init() {
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
|
||||
*/
|
||||
adc_handle_.Instance = ADC1;
|
||||
adc_handle_.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
|
||||
adc_handle_.Init.Resolution = ADC_RESOLUTION_12B;
|
||||
adc_handle_.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
adc_handle_.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
|
||||
adc_handle_.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
adc_handle_.Init.LowPowerAutoWait = DISABLE;
|
||||
adc_handle_.Init.LowPowerAutoPowerOff = DISABLE;
|
||||
adc_handle_.Init.ContinuousConvMode = DISABLE;
|
||||
adc_handle_.Init.DiscontinuousConvMode = DISABLE;
|
||||
adc_handle_.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
adc_handle_.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||
adc_handle_.Init.DMAContinuousRequests = DISABLE;
|
||||
adc_handle_.Init.Overrun = ADC_OVR_DATA_PRESERVED;
|
||||
if (HAL_ADC_Init(&adc_handle_) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure for the selected ADC regular channel to be converted.
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_0;
|
||||
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||
if (HAL_ADC_ConfigChannel(&adc_handle_, &sConfig) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
std::expected<units::voltage, hal::adc::error> hal::adc_stm32::get_reading() {
|
||||
HAL_ADC_Start(&adc_handle_);
|
||||
if(HAL_ADC_PollForConversion(&adc_handle_, 1000) != HAL_OK) {
|
||||
return std::unexpected(hal::adc::error::timeout);
|
||||
}
|
||||
|
||||
auto adc_val = HAL_ADC_GetValue(&adc_handle_);
|
||||
|
||||
return ref_voltage_ * adc_val / 4096.f;
|
||||
}
|
||||
19
Chapter17/cib/hal/gpio/inc/gpio.hpp
Normal file
19
Chapter17/cib/hal/gpio/inc/gpio.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
class gpio
|
||||
{
|
||||
public:
|
||||
gpio(const std::function<void()> & on_press = nullptr);
|
||||
void execute_interrupt_handler() const;
|
||||
|
||||
[[nodiscard]] virtual bool is_interrupt_generated() const = 0;
|
||||
virtual void clear_interrupt_flag() const = 0;
|
||||
private:
|
||||
std::function<void()> on_press_;
|
||||
};
|
||||
}; // namespace hal
|
||||
19
Chapter17/cib/hal/gpio/inc/gpio_interrupt_manager.hpp
Normal file
19
Chapter17/cib/hal/gpio/inc/gpio_interrupt_manager.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include <gpio.hpp>
|
||||
|
||||
namespace hal {
|
||||
|
||||
struct gpio_interrupt_manager {
|
||||
static void register_interrupt_handler(gpio * pin);
|
||||
|
||||
static void execute_interrupt_handlers();
|
||||
|
||||
static constexpr std::size_t c_gpio_handlers_num = 16;
|
||||
static inline std::array<gpio*, c_gpio_handlers_num> gpio_handlers{};
|
||||
static inline std::size_t w_idx = 0;
|
||||
};
|
||||
};
|
||||
70
Chapter17/cib/hal/gpio/inc/gpio_stm32.hpp
Normal file
70
Chapter17/cib/hal/gpio/inc/gpio_stm32.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <gpio.hpp>
|
||||
|
||||
#include <stm32f072xb.h>
|
||||
|
||||
namespace hal {
|
||||
|
||||
enum class pin : uint16_t {
|
||||
p_invalid = 0,
|
||||
p0 = 0x0001U,
|
||||
p1 = 0x0002U,
|
||||
p2 = 0x0004U,
|
||||
p3 = 0x0008U,
|
||||
p4 = 0x0010U,
|
||||
p5 = 0x0020U,
|
||||
p6 = 0x0040U,
|
||||
p7 = 0x0080U,
|
||||
p8 = 0x0100U,
|
||||
p9 = 0x0200U,
|
||||
p10 = 0x0400U,
|
||||
p11 = 0x0800U,
|
||||
p12 = 0x1000U,
|
||||
p13 = 0x2000U,
|
||||
p14 = 0x4000U,
|
||||
p15 = 0x8000U,
|
||||
all = 0xFFFFU
|
||||
};
|
||||
|
||||
struct port_a {
|
||||
static constexpr uint8_t c_pin_num = 16;
|
||||
static inline GPIO_TypeDef * port = reinterpret_cast<GPIO_TypeDef*>(GPIOA);
|
||||
static void init_clock () {
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Port>
|
||||
class gpio_stm32 : public gpio {
|
||||
public:
|
||||
gpio_stm32(pin the_pin, const std::function<void()> & on_press = nullptr)
|
||||
: gpio(on_press), the_pin_(the_pin) {
|
||||
Port::init_clock();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct { static_cast<uint16_t>(the_pin),
|
||||
GPIO_MODE_IT_RISING,
|
||||
GPIO_NOPULL,
|
||||
GPIO_SPEED_FREQ_LOW,
|
||||
0 };
|
||||
HAL_GPIO_Init(Port::port, &GPIO_InitStruct);
|
||||
|
||||
if(on_press) {
|
||||
enable_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_interrupt_generated() const override {
|
||||
return __HAL_GPIO_EXTI_GET_IT(static_cast<uint16_t>(the_pin_));
|
||||
}
|
||||
void clear_interrupt_flag() const override {
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(static_cast<uint16_t>(the_pin_));
|
||||
}
|
||||
private:
|
||||
pin the_pin_ = pin::p_invalid;
|
||||
|
||||
void enable_interrupt() {
|
||||
// TODO: check EXTI line macro according to pin used
|
||||
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
|
||||
}
|
||||
};
|
||||
};
|
||||
21
Chapter17/cib/hal/gpio/src/gpio.cpp
Normal file
21
Chapter17/cib/hal/gpio/src/gpio.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <gpio.hpp>
|
||||
#include <gpio_interrupt_manager.hpp>
|
||||
|
||||
namespace hal {
|
||||
|
||||
gpio::gpio(const std::function<void()> & on_press) {
|
||||
on_press_ = on_press;
|
||||
gpio_interrupt_manager::register_interrupt_handler(this);
|
||||
}
|
||||
|
||||
void gpio::execute_interrupt_handler () const {
|
||||
if(is_interrupt_generated())
|
||||
{
|
||||
clear_interrupt_flag();
|
||||
if(on_press_) {
|
||||
on_press_();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
17
Chapter17/cib/hal/gpio/src/gpio_interrupt_manager.cpp
Normal file
17
Chapter17/cib/hal/gpio/src/gpio_interrupt_manager.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <gpio_interrupt_manager.hpp>
|
||||
|
||||
namespace hal {
|
||||
|
||||
void gpio_interrupt_manager::register_interrupt_handler(gpio * pin) {
|
||||
gpio_handlers.at(w_idx++) = pin;
|
||||
}
|
||||
|
||||
void gpio_interrupt_manager::execute_interrupt_handlers() {
|
||||
for(std::size_t i = 0; i < w_idx; i++) {
|
||||
gpio_handlers[i]->execute_interrupt_handler();
|
||||
}
|
||||
}
|
||||
extern "C" void EXTI4_15_IRQHandler(void) {
|
||||
gpio_interrupt_manager::execute_interrupt_handlers();
|
||||
}
|
||||
};
|
||||
33
Chapter17/cib/hal/inc/hal.hpp
Normal file
33
Chapter17/cib/hal/inc/hal.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <stm32f0xx_hal.h>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
inline void init()
|
||||
{
|
||||
HAL_Init();
|
||||
}
|
||||
|
||||
inline std::uint32_t get_pc()
|
||||
{
|
||||
std::uint32_t pc;
|
||||
__asm volatile ("mov %0, pc" : "=r" (pc) );
|
||||
return pc;
|
||||
}
|
||||
|
||||
struct time
|
||||
{
|
||||
static std::uint32_t get_ms()
|
||||
{
|
||||
return HAL_GetTick();
|
||||
}
|
||||
|
||||
static void delay_ms(uint32_t delay)
|
||||
{
|
||||
HAL_Delay(delay);
|
||||
}
|
||||
};
|
||||
}; // namespace hal
|
||||
21
Chapter17/cib/hal/uart/inc/stm32f0xx_hal_uart.hpp
Normal file
21
Chapter17/cib/hal/uart/inc/stm32f0xx_hal_uart.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <stm32f0xx_hal.h>
|
||||
#include <stm32f072xb.h>
|
||||
|
||||
namespace hal::stm32{
|
||||
struct uart {
|
||||
uart() = delete;
|
||||
|
||||
static inline HAL_StatusTypeDef init(UART_HandleTypeDef *huart) {
|
||||
return HAL_UART_Init(huart);
|
||||
}
|
||||
|
||||
static inline HAL_StatusTypeDef transmit(UART_HandleTypeDef *huart,
|
||||
uint8_t *pData,
|
||||
uint16_t Size,
|
||||
uint32_t Timeout) {
|
||||
return HAL_UART_Transmit(huart, pData, Size, Timeout);
|
||||
}
|
||||
};
|
||||
};
|
||||
14
Chapter17/cib/hal/uart/inc/uart.hpp
Normal file
14
Chapter17/cib/hal/uart/inc/uart.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
class uart
|
||||
{
|
||||
public:
|
||||
virtual void init(std::uint32_t baudrate) = 0;
|
||||
virtual void write(std::span<const char> data) = 0;
|
||||
};
|
||||
}; // namespace hal
|
||||
46
Chapter17/cib/hal/uart/inc/uart_stm32.hpp
Normal file
46
Chapter17/cib/hal/uart/inc/uart_stm32.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <cstdint>
|
||||
|
||||
#include <uart.hpp>
|
||||
|
||||
#include <stm32f0xx_hal_uart.hpp>
|
||||
|
||||
namespace hal
|
||||
{
|
||||
template <typename HalUart>
|
||||
class uart_stm32 : public uart
|
||||
{
|
||||
public:
|
||||
uart_stm32(USART_TypeDef *inst) : instance_(inst) {}
|
||||
|
||||
void init(std::uint32_t baudrate = c_baudrate_default) override {
|
||||
huart_.Instance = instance_;
|
||||
huart_.Init.BaudRate = baudrate;
|
||||
huart_.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart_.Init.StopBits = UART_STOPBITS_1;
|
||||
huart_.Init.Parity = UART_PARITY_NONE;
|
||||
huart_.Init.Mode = UART_MODE_TX_RX;
|
||||
huart_.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart_.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
huart_.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
huart_.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
// TODO: add GPIO initialization for real hardware
|
||||
huart_.MspInitCallback = nullptr;
|
||||
HalUart::init(&huart_);
|
||||
}
|
||||
void write(std::span<const char> data) override {
|
||||
// we must cast away costness due to ST HAL's API
|
||||
char * data_ptr = const_cast<char *>(data.data());
|
||||
HalUart::transmit(&huart_, reinterpret_cast<uint8_t *>(data_ptr), data.size(),
|
||||
HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
private:
|
||||
UART_HandleTypeDef huart_;
|
||||
USART_TypeDef *instance_;
|
||||
std::uint32_t baudrate_;
|
||||
static constexpr std::uint32_t c_baudrate_default = 115200;
|
||||
};
|
||||
}; // namespace hal
|
||||
34
Chapter17/cib/hal/uart/src/uart_stm32.cpp
Normal file
34
Chapter17/cib/hal/uart/src/uart_stm32.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <uart_stm32.hpp>
|
||||
|
||||
template <typename HalUart>
|
||||
hal::uart_stm32<HalUart>::uart_stm32(USART_TypeDef *inst)
|
||||
: instance_(inst)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename HalUart>
|
||||
void hal::uart_stm32<HalUart>::init(std::uint32_t baudrate)
|
||||
{
|
||||
huart_.Instance = instance_;
|
||||
huart_.Init.BaudRate = baudrate;
|
||||
huart_.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart_.Init.StopBits = UART_STOPBITS_1;
|
||||
huart_.Init.Parity = UART_PARITY_NONE;
|
||||
huart_.Init.Mode = UART_MODE_TX_RX;
|
||||
huart_.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart_.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
huart_.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
huart_.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
// TODO: add GPIO initialization for real hardware
|
||||
huart_.MspInitCallback = nullptr;
|
||||
HalUart::init(&huart_);
|
||||
}
|
||||
|
||||
template <typename HalUart>
|
||||
void hal::uart_stm32<HalUart>::write(std::span<const char> data)
|
||||
{
|
||||
// we must cast away costness due to ST HAL's API
|
||||
char * data_ptr = const_cast<char *>(data.data());
|
||||
HalUart::transmit(&huart_, reinterpret_cast<uint8_t *>(data_ptr), data.size(),
|
||||
HAL_MAX_DELAY);
|
||||
}
|
||||
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
|
||||
2900
Chapter17/cib/libs/boost/sml.hpp
Normal file
2900
Chapter17/cib/libs/boost/sml.hpp
Normal file
File diff suppressed because it is too large
Load Diff
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
|
||||
51
Chapter17/cib/libs/etl/.clang-format
Normal file
51
Chapter17/cib/libs/etl/.clang-format
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
#------------------------------------
|
||||
# Configuration for clang-format v12
|
||||
#------------------------------------
|
||||
|
||||
Language: Cpp
|
||||
|
||||
SortIncludes: true
|
||||
|
||||
BasedOnStyle: Chromium
|
||||
|
||||
BinPackParameters: false
|
||||
BitFieldColonSpacing: Both
|
||||
|
||||
BreakBeforeBraces: Allman
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
ConstructorInitializerIndentWidth: '2'
|
||||
|
||||
NamespaceIndentation: All
|
||||
IndentPPDirectives: BeforeHash
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: '0'
|
||||
ContinuationIndentWidth: '2'
|
||||
UseTab: Never
|
||||
TabWidth: '2'
|
||||
IndentWidth: '2'
|
||||
AccessModifierOffset : '-2'
|
||||
IndentCaseLabels: false
|
||||
Cpp11BracedListStyle: 'true'
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveDeclarations: true
|
||||
|
||||
#------------------------------------
|
||||
# Configurations not supported by clang-format v12
|
||||
#------------------------------------
|
||||
# BreakInheritanceList: AfterComma
|
||||
# EmptyLineBeforeAccessModifier: Always
|
||||
# EmptyLineAfterAccessModifier: Always
|
||||
# ReferenceAlignment: Left
|
||||
|
||||
...
|
||||
82
Chapter17/cib/libs/etl/CMakeLists.txt
Normal file
82
Chapter17/cib/libs/etl/CMakeLists.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
#######################################################################
|
||||
# The Embedded Template Library (https://www.etlcpp.com/)
|
||||
#######################################################################
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/helpers.cmake)
|
||||
|
||||
set(MSG_PREFIX "etl |")
|
||||
determine_version_with_git(${GIT_DIR_LOOKUP_POLICY})
|
||||
if(NOT ETL_VERSION)
|
||||
determine_version_with_file("version.txt")
|
||||
endif()
|
||||
|
||||
project(etl VERSION ${ETL_VERSION} LANGUAGES CXX)
|
||||
|
||||
option(BUILD_TESTS "Build unit tests" OFF)
|
||||
option(NO_STL "No STL" OFF)
|
||||
# There is a bug on old gcc versions for some targets that causes all system headers
|
||||
# to be implicitly wrapped with 'extern "C"'
|
||||
# Users can add set(NO_SYSTEM_INCLUDE ON) to their top level CMakeLists.txt to work around this.
|
||||
option(NO_SYSTEM_INCLUDE "Do not include with -isystem" OFF)
|
||||
if (NO_SYSTEM_INCLUDE)
|
||||
set(INCLUDE_SPECIFIER "")
|
||||
else()
|
||||
set(INCLUDE_SPECIFIER "SYSTEM")
|
||||
endif()
|
||||
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
# This allows users which use the add_subdirectory or FetchContent
|
||||
# to use the same target as users which use find_package
|
||||
add_library(etl::etl ALIAS ${PROJECT_NAME})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} ${INCLUDE_SPECIFIER} INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} INTERFACE)
|
||||
|
||||
# only install if top level project
|
||||
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
|
||||
# Steps here based on excellent guide: https://dominikberner.ch/cmake-interface-lib/
|
||||
# Which also details all steps
|
||||
include(CMakePackageConfigHelpers)
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
if(ETL_VERSION)
|
||||
# Generate the package configuration files using CMake provided macros
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_NAME}ConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
ARCH_INDEPENDENT
|
||||
)
|
||||
endif()
|
||||
configure_package_config_file(
|
||||
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
|
||||
# Install target file, then package configuration files, and finally the headers
|
||||
install(EXPORT ${PROJECT_NAME}Targets
|
||||
FILE ${PROJECT_NAME}Targets.cmake
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/etl DESTINATION include)
|
||||
|
||||
endif()
|
||||
|
||||
if (BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
2401
Chapter17/cib/libs/etl/Doxyfile
Normal file
2401
Chapter17/cib/libs/etl/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
19
Chapter17/cib/libs/etl/LICENSE
Normal file
19
Chapter17/cib/libs/etl/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
147
Chapter17/cib/libs/etl/README.md
Normal file
147
Chapter17/cib/libs/etl/README.md
Normal file
@@ -0,0 +1,147 @@
|
||||
Embedded Template Library (ETL)
|
||||
-------------------------
|
||||
|
||||

|
||||
[](https://img.shields.io/github/release-date/jwellbelove/etl?color=%231182c3)
|
||||
[](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||
[](https://ci.appveyor.com/project/jwellbelove/etl/branch/master)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
[](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade)
|
||||
|
||||
[](https://www.etlcpp.com/sponsor.html)
|
||||
|
||||
[Project documentation](https://www.etlcpp.com/)
|
||||
|
||||
## Motivation
|
||||
|
||||
C++ is a great language to use for embedded applications and templates are a powerful aspect. The standard library can offer a great deal of well tested functionality, but there are some parts of the standard library that do not fit well with deterministic behaviour and limited resource requirements. These limitations usually preclude the use of dynamically allocated memory and containers with open ended sizes.
|
||||
|
||||
What is needed is a template library where the user can declare the size, or maximum size of any object upfront. Most embedded compilers do not currently support the standard beyond C++ 03, therefore excluding the programmer from using the enhanced features of the later library.
|
||||
|
||||
This is what the ETL attempts to achieve.
|
||||
|
||||
## Summary
|
||||
|
||||
The ETL is not designed to completely replace the STL, but complement it.
|
||||
Its design objective covers three areas.
|
||||
|
||||
- Create a set of containers where the size or maximum size is determined at compile time. These containers are direct equivalents of those supplied in the STL.
|
||||
- Be compatible with C++ 03 but implement as many of the C++ 11/14/17/20 additions as possible.
|
||||
- Add other useful components that are not present in the standard library.
|
||||
|
||||
The embedded template library has been designed for lower resource embedded applications.
|
||||
It contains a set of containers, algorithms and utilities, some of which emulate parts of the STL.
|
||||
There is no dynamic memory allocation. The library makes no use of the heap. All of the containers have a fixed capacity allowing all memory allocation to be determined at compile time.
|
||||
The library is intended for any compiler that supports C++98/03/11/14/17/20.
|
||||
|
||||
## Main features
|
||||
|
||||
- Cross platform. This library is not specific to any processor type.
|
||||
- No dynamic memory allocation
|
||||
- No RTTI required
|
||||
- Very little use of virtual functions. They are used only when they are absolutely necessary for the required functionality
|
||||
- A set of fixed capacity containers. (array, bitset, deque, forward_list, list, queue, stack, vector, map, set, etc.)
|
||||
- As the storage for all of the container types is allocated as a contiguous block, they are extremely cache friendly
|
||||
- Templated compile time constants
|
||||
- Templated design pattern base classes (Visitor, Observer)
|
||||
- Reverse engineered C++ 0x11 features (type traits, algorithms, containers etc.)
|
||||
- Type-safe enumerations
|
||||
- Type-safe typedefs
|
||||
- 8, 16, 32 & 64 bit CRC calculations
|
||||
- Checksums & hash functions
|
||||
- Variants (a type that can store many types in a type-safe interface)
|
||||
- Choice of asserts, exceptions, error handler or no checks on errors
|
||||
- Unit tested (currently over 9400 tests), using VS2022, GCC 12, Clang 14.
|
||||
- Many utilities for template support.
|
||||
- Easy to read and documented source.
|
||||
- Free support via email, GitHub and Slack
|
||||
|
||||
Any help porting the library to work under different platforms and compilers would be gratefully received.
|
||||
I am especially interested in people who are using Keil, IAR, Green Hills, TI Code Composer etc, bare metal or RTOS, and DSPs.
|
||||
|
||||
See (https://www.etlcpp.com) for up-to-date information.
|
||||
|
||||
## Installing this library
|
||||
|
||||
You can find the setup steps [here](https://www.etlcpp.com/setup.html).
|
||||
|
||||
### CMake
|
||||
|
||||
One way to use this library is to drop it somewhere in your project directory
|
||||
and then make the library available by using `add_subdirectory`
|
||||
|
||||
```cmake
|
||||
add_subdirectory(etl)
|
||||
add_executable(foo main.cpp)
|
||||
target_link_libraries(foo PRIVATE etl::etl)
|
||||
```
|
||||
|
||||
If ETL library is used as a Git submodule it may require additional configuration for proper ETL version resolution by allowing the lookup for Git folder outside of the library root directory.
|
||||
|
||||
```cmake
|
||||
set(GIT_DIR_LOOKUP_POLICY ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
|
||||
add_subdirectory(etl)
|
||||
```
|
||||
|
||||
If you want to install this library with CMake, you can perform the following steps. On Linux,
|
||||
super user rights might be required to install the library, so it might be necessary to add
|
||||
`sudo` before the last command:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/ETLCPP/etl.git
|
||||
cd etl
|
||||
git checkout <targetVersion>
|
||||
cmake -B build .
|
||||
cmake --install build/
|
||||
```
|
||||
|
||||
After the library has been installed, you can use
|
||||
[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) to use the library.
|
||||
Replace `<majorVersionRequirement>` with your desired major version:
|
||||
|
||||
```cmake
|
||||
find_package(etl <majorVersionRequirement>)
|
||||
add_executable(foo main.cpp)
|
||||
target_link_libraries(foo PRIVATE etl::etl)
|
||||
```
|
||||
|
||||
|
||||
Alternatively you can use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html),
|
||||
replacing `<targetVersion>` with the version to install based on a git tag:
|
||||
|
||||
```sh
|
||||
Include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
etl
|
||||
GIT_REPOSITORY https://github.com/ETLCPP/etl
|
||||
GIT_TAG <targetVersion>
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(etl)
|
||||
|
||||
add_executable(foo main.cpp)
|
||||
target_link_libraries(foo PRIVATE etl::etl)
|
||||
```
|
||||
|
||||
## Arduino library
|
||||
|
||||
The content of this repo is available as a library in the Arduino IDE (search for the "Embedded Template Library" in the IDE library manager). The Arduino library repository is available at ```https://github.com/ETLCPP/etl-arduino```, see there for more details.
|
||||
26
Chapter17/cib/libs/etl/appveyor.yml
Normal file
26
Chapter17/cib/libs/etl/appveyor.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
image: Visual Studio 2022
|
||||
configuration:
|
||||
- Debug MSVC C++14
|
||||
- Debug MSVC C++14 - No STL
|
||||
- Debug MSVC C++17
|
||||
- Debug MSVC C++17 - No STL
|
||||
- Debug MSVC C++20
|
||||
- Debug MSVC C++20 - No STL
|
||||
clone_folder: c:\projects\etl
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive
|
||||
build:
|
||||
project: test/vs2022/etl.vcxproj
|
||||
verbosity: minimal
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://hooks.slack.com/services/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
|
||||
method: POST
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
||||
|
||||
80
Chapter17/cib/libs/etl/arduino/Embedded_Template_Library.h
Normal file
80
Chapter17/cib/libs/etl/arduino/Embedded_Template_Library.h
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
#ifndef ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED
|
||||
#define ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED
|
||||
|
||||
#if defined(TEENSYDUINO)
|
||||
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
#define ARDUINO_BOARD "Teensy 2.0"
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define ARDUINO_BOARD "Teensy++ 2.0"
|
||||
#elif defined(__MK20DX128__)
|
||||
#define ARDUINO_BOARD "Teensy 3.0"
|
||||
#elif defined(__MK20DX256__)
|
||||
#define ARDUINO_BOARD "Teensy 3.2" // and Teensy 3.1
|
||||
#elif defined(__MKL26Z64__)
|
||||
#define ARDUINO_BOARD "Teensy LC"
|
||||
#elif defined(__MK64FX512__)
|
||||
#define ARDUINO_BOARD "Teensy 3.5"
|
||||
#elif defined(__MK66FX1M0__)
|
||||
#define ARDUINO_BOARD "Teensy 3.6"
|
||||
#else
|
||||
#define ARDUINO_BOARD "Unknown"
|
||||
#endif
|
||||
|
||||
#else // --------------- Arduino ------------------
|
||||
|
||||
#if defined(ARDUINO_AVR_ADK)
|
||||
#define ARDUINO_BOARD "Mega Adk"
|
||||
#elif defined(ARDUINO_AVR_BT)
|
||||
#define ARDUINO_BOARD "Bt"
|
||||
#elif defined(ARDUINO_AVR_DUEMILANOVE)
|
||||
#define ARDUINO_BOARD "Duemilanove"
|
||||
#elif defined(ARDUINO_AVR_ESPLORA)
|
||||
#define ARDUINO_BOARD "Esplora"
|
||||
#elif defined(ARDUINO_AVR_ETHERNET)
|
||||
#define ARDUINO_BOARD "Ethernet"
|
||||
#elif defined(ARDUINO_AVR_FIO)
|
||||
#define ARDUINO_BOARD "Fio"
|
||||
#elif defined(ARDUINO_AVR_GEMMA)
|
||||
#define ARDUINO_BOARD "Gemma"
|
||||
#elif defined(ARDUINO_AVR_LEONARDO)
|
||||
#define ARDUINO_BOARD "Leonardo"
|
||||
#elif defined(ARDUINO_AVR_LILYPAD)
|
||||
#define ARDUINO_BOARD "Lilypad"
|
||||
#elif defined(ARDUINO_AVR_LILYPAD_USB)
|
||||
#define ARDUINO_BOARD "Lilypad Usb"
|
||||
#elif defined(ARDUINO_AVR_MEGA)
|
||||
#define ARDUINO_BOARD "Mega"
|
||||
#elif defined(ARDUINO_AVR_MEGA2560)
|
||||
#define ARDUINO_BOARD "Mega 2560"
|
||||
#elif defined(ARDUINO_AVR_MICRO)
|
||||
#define ARDUINO_BOARD "Micro"
|
||||
#elif defined(ARDUINO_AVR_MINI)
|
||||
#define ARDUINO_BOARD "Mini"
|
||||
#elif defined(ARDUINO_AVR_NANO)
|
||||
#define ARDUINO_BOARD "Nano"
|
||||
#elif defined(ARDUINO_AVR_NG)
|
||||
#define ARDUINO_BOARD "NG"
|
||||
#elif defined(ARDUINO_AVR_PRO)
|
||||
#define ARDUINO_BOARD "Pro"
|
||||
#elif defined(ARDUINO_AVR_ROBOT_CONTROL)
|
||||
#define ARDUINO_BOARD "Robot Ctrl"
|
||||
#elif defined(ARDUINO_AVR_ROBOT_MOTOR)
|
||||
#define ARDUINO_BOARD "Robot Motor"
|
||||
#elif defined(ARDUINO_AVR_UNO)
|
||||
#define ARDUINO_BOARD "Uno"
|
||||
#elif defined(ARDUINO_AVR_YUN)
|
||||
#define ARDUINO_BOARD "Yun"
|
||||
#elif defined(ARDUINO_SAM_DUE)
|
||||
#define ARDUINO_BOARD "Due"
|
||||
#elif defined(ARDUINO_SAMD_ZERO)
|
||||
#define ARDUINO_BOARD "Zero"
|
||||
#elif defined(ARDUINO_ARC32_TOOLS)
|
||||
#define ARDUINO_BOARD "101"
|
||||
#else
|
||||
#define ARDUINO_BOARD "Unknown"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "Embedded_Template_Library.h" // This is required for any more etl import when using Arduino IDE
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// make sure that we do not rely on the STL
|
||||
#define ETL_NO_STL
|
||||
|
||||
#include "Embedded_Template_Library.h"
|
||||
#include "etl/vector.h"
|
||||
|
||||
template <typename T>
|
||||
void print_vector(etl::ivector<T> const & vec_in)
|
||||
{
|
||||
Serial.print(F("print vector content | size ")); Serial.print(vec_in.size()); Serial.print(F(" | capacity ")); Serial.println(vec_in.capacity());
|
||||
Serial.print(F("content | "));
|
||||
|
||||
for (T const & elem : vec_in)
|
||||
{
|
||||
Serial.print(elem);
|
||||
Serial.print(F(" | "));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
delay(100);
|
||||
Serial.println(F("booted"));
|
||||
|
||||
etl::vector<int, 12> vec_int;
|
||||
|
||||
Serial.println(F("initialized vec_int"));
|
||||
print_vector(vec_int);
|
||||
|
||||
vec_int.push_back(1);
|
||||
vec_int.push_back(2);
|
||||
Serial.println(F("pushed to vec_int"));
|
||||
print_vector(vec_int);
|
||||
|
||||
vec_int.pop_back();
|
||||
Serial.println(F("pop from vec_int; returns no value"));
|
||||
print_vector(vec_int);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
39
Chapter17/cib/libs/etl/arduino/library-arduino.json
Normal file
39
Chapter17/cib/libs/etl/arduino/library-arduino.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Embedded Template Library ETL",
|
||||
"version": "20.39.0",
|
||||
"authors": {
|
||||
"name": "John Wellbelove",
|
||||
"email": "john.wellbelove@etlcpp.com"
|
||||
},
|
||||
"homepage": "https://www.etlcpp.com/",
|
||||
"license": "MIT",
|
||||
"description": "ETL. A C++ template library tailored for embedded systems. Directories formatted for Arduino",
|
||||
"keywords": "c-plus-plus, cpp, algorithms, containers, templates",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ETLCPP/etl-arduino.git"
|
||||
},
|
||||
"build": {
|
||||
"includeDir": "include"
|
||||
},
|
||||
"export": {
|
||||
"include": [
|
||||
"include",
|
||||
"examples",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"exclude": [
|
||||
"include/etl/experimental",
|
||||
"include/etl/deprecated",
|
||||
"**/__vm",
|
||||
"**/.vs",
|
||||
"**/*.filters",
|
||||
"**/*.log",
|
||||
"**/*.tmp"
|
||||
]
|
||||
},
|
||||
"platforms": "*",
|
||||
"frameworks": "*"
|
||||
}
|
||||
|
||||
10
Chapter17/cib/libs/etl/arduino/library-arduino.properties
Normal file
10
Chapter17/cib/libs/etl/arduino/library-arduino.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=Embedded Template Library ETL
|
||||
version=20.39.0
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
license=MIT
|
||||
sentence=ETL. A C++ template library tailored for embedded systems.
|
||||
paragraph=
|
||||
category=Other
|
||||
url=https://www.etlcpp.com/
|
||||
architectures=*
|
||||
284
Chapter17/cib/libs/etl/cmake/GetGitRevisionDescription.cmake
Normal file
284
Chapter17/cib/libs/etl/cmake/GetGitRevisionDescription.cmake
Normal file
@@ -0,0 +1,284 @@
|
||||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the working tree (--dirty option),
|
||||
# and adjusting the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# git_local_changes(<var>)
|
||||
#
|
||||
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
|
||||
# Uses the return code of "git diff-index --quiet HEAD --".
|
||||
# Does not regard untracked files.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
#
|
||||
# Copyright 2009-2013, Iowa State University.
|
||||
# Copyright 2013-2020, Ryan Pavlik
|
||||
# Copyright 2013-2020, Contributors
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
# 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)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
# Function _git_find_closest_git_dir finds the next closest .git directory
|
||||
# that is part of any directory in the path defined by _start_dir.
|
||||
# The result is returned in the parent scope variable whose name is passed
|
||||
# as variable _git_dir_var. If no .git directory can be found, the
|
||||
# function returns an empty string via _git_dir_var.
|
||||
#
|
||||
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
||||
# neither foo nor bar contain a file/directory .git. This will return
|
||||
# C:/bla/.git
|
||||
#
|
||||
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
||||
set(cur_dir "${_start_dir}")
|
||||
set(git_dir "${_start_dir}/.git")
|
||||
while(NOT EXISTS "${git_dir}")
|
||||
# .git dir not found, search parent directories
|
||||
set(git_previous_parent "${cur_dir}")
|
||||
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
|
||||
if(cur_dir STREQUAL git_previous_parent)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_git_dir_var}
|
||||
""
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(git_dir "${cur_dir}/.git")
|
||||
endwhile()
|
||||
set(${_git_dir_var}
|
||||
"${git_dir}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
|
||||
|
||||
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
|
||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
|
||||
else()
|
||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
|
||||
endif()
|
||||
if(NOT "${GIT_DIR}" STREQUAL "")
|
||||
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
|
||||
"${GIT_DIR}")
|
||||
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
|
||||
# We've gone above the CMake root dir.
|
||||
set(GIT_DIR "")
|
||||
endif()
|
||||
endif()
|
||||
if("${GIT_DIR}" STREQUAL "")
|
||||
set(${_refspecvar}
|
||||
"GITDIR-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
set(${_hashvar}
|
||||
"GITDIR-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check if the current source dir is a git submodule or a worktree.
|
||||
# In both cases .git is a file instead of a directory.
|
||||
#
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
# The following git command will return a non empty string that
|
||||
# points to the super project working tree if the current
|
||||
# source dir is inside a git submodule.
|
||||
# Otherwise the command will return an empty string.
|
||||
#
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse
|
||||
--show-superproject-working-tree
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT "${out}" STREQUAL "")
|
||||
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
|
||||
${submodule})
|
||||
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
|
||||
ABSOLUTE)
|
||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
||||
else()
|
||||
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
|
||||
file(READ ${GIT_DIR} worktree_ref)
|
||||
# The .git directory contains a path to the worktree information directory
|
||||
# inside the parent git repo of the worktree.
|
||||
#
|
||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
|
||||
${worktree_ref})
|
||||
string(STRIP ${git_worktree_dir} git_worktree_dir)
|
||||
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
|
||||
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
|
||||
endif()
|
||||
else()
|
||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake" @ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar}
|
||||
"${HEAD_REF}"
|
||||
PARENT_SCOPE)
|
||||
set(${_hashvar}
|
||||
"${HEAD_HASH}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash ${ARGN})
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe_working_tree _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_local_changes _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(res EQUAL 0)
|
||||
set(${_var}
|
||||
"CLEAN"
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
set(${_var}
|
||||
"DIRTY"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Internal file for GetGitRevisionDescription.cmake
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright 2009-2012, Iowa State University
|
||||
# Copyright 2011-2015, Contributors
|
||||
# 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)
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
set(HEAD_HASH)
|
||||
|
||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
||||
|
||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
||||
if(HEAD_CONTENTS MATCHES "ref")
|
||||
# named branch
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
else()
|
||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
||||
4
Chapter17/cib/libs/etl/cmake/etlConfig.cmake.in
Normal file
4
Chapter17/cib/libs/etl/cmake/etlConfig.cmake.in
Normal file
@@ -0,0 +1,4 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
35
Chapter17/cib/libs/etl/cmake/helpers.cmake
Normal file
35
Chapter17/cib/libs/etl/cmake/helpers.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
function(determine_version_with_file VER_FILE_NAME)
|
||||
file(READ ${VER_FILE_NAME} ETL_VERSION_RAW)
|
||||
# Remove trailing whitespaces and/or newline
|
||||
string(STRIP ${ETL_VERSION_RAW} ETL_VERSION)
|
||||
set(ETL_VERSION ${ETL_VERSION} CACHE STRING
|
||||
"ETL version determined from version.txt" FORCE
|
||||
)
|
||||
message(STATUS "${MSG_PREFIX} Determined ETL version ${ETL_VERSION} from version.txt file")
|
||||
endfunction()
|
||||
|
||||
function(determine_version_with_git)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake)
|
||||
git_describe(VERSION ${ARGN})
|
||||
string(FIND ${VERSION} "." VALID_VERSION)
|
||||
if(VALID_VERSION EQUAL -1)
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
# only warn if this is the top-level project, since we may be
|
||||
# building from a tarball as a subproject
|
||||
message(WARNING "Version string ${VERSION} retrieved with git describe is invalid")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
message(STATUS "${MSG_PREFIX} Version string determined with git describe: ${VERSION}")
|
||||
# Parse the version information into pieces.
|
||||
string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1" VERSION_SHA1 "${VERSION}")
|
||||
set(ETL_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
|
||||
set(ETL_VERSION ${ETL_VERSION} CACHE STRING
|
||||
"ETL version determined with git describe" FORCE
|
||||
)
|
||||
message(STATUS "${MSG_PREFIX} Determined ETL version ${ETL_VERSION} from the git tag")
|
||||
endfunction()
|
||||
4
Chapter17/cib/libs/etl/examples/ArmTimerCallbacks - C++/.gitignore
vendored
Normal file
4
Chapter17/cib/libs/etl/examples/ArmTimerCallbacks - C++/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
Objects/
|
||||
RTE/
|
||||
Listings/
|
||||
DebugConfig/
|
||||
@@ -0,0 +1,487 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
||||
|
||||
<SchemaVersion>2.1</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Targets>
|
||||
<Target>
|
||||
<TargetName>Target 1</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>5060750::V5.06 update 6 (build 750)::.\ARMCC</pCCUsed>
|
||||
<uAC6>0</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
<Device>STM32F401RETx</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32F4xx_DFP.2.15.0</PackID>
|
||||
<PackURL>http://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000,0x18000) IROM(0x08000000,0x80000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32F401RETx$CMSIS\Flash\STM32F4xx_512.FLM))</FlashDriverDll>
|
||||
<DeviceId>0</DeviceId>
|
||||
<RegisterFile>$$Device:STM32F401RETx$Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h</RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
<Linker></Linker>
|
||||
<OHString></OHString>
|
||||
<InfinionOptionDll></InfinionOptionDll>
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<SFDFile>$$Device:STM32F401RETx$CMSIS\SVD\STM32F401xE.svd</SFDFile>
|
||||
<bCustSvd>0</bCustSvd>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
<IncludePath></IncludePath>
|
||||
<LibPath></LibPath>
|
||||
<RegisterFilePath></RegisterFilePath>
|
||||
<DBRegisterFilePath></DBRegisterFilePath>
|
||||
<TargetStatus>
|
||||
<Error>0</Error>
|
||||
<ExitCodeStop>0</ExitCodeStop>
|
||||
<ButtonStop>0</ButtonStop>
|
||||
<NotGenerated>0</NotGenerated>
|
||||
<InvalidFlash>1</InvalidFlash>
|
||||
</TargetStatus>
|
||||
<OutputDirectory>.\Objects\</OutputDirectory>
|
||||
<OutputName>ArmTimerCallbacks</OutputName>
|
||||
<CreateExecutable>1</CreateExecutable>
|
||||
<CreateLib>0</CreateLib>
|
||||
<CreateHexFile>0</CreateHexFile>
|
||||
<DebugInformation>1</DebugInformation>
|
||||
<BrowseInformation>1</BrowseInformation>
|
||||
<ListingPath>.\Listings\</ListingPath>
|
||||
<HexFormatSelection>1</HexFormatSelection>
|
||||
<Merge32K>0</Merge32K>
|
||||
<CreateBatchFile>0</CreateBatchFile>
|
||||
<BeforeCompile>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopU1X>0</nStopU1X>
|
||||
<nStopU2X>0</nStopU2X>
|
||||
</BeforeCompile>
|
||||
<BeforeMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopB1X>0</nStopB1X>
|
||||
<nStopB2X>0</nStopB2X>
|
||||
</BeforeMake>
|
||||
<AfterMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopA1X>0</nStopA1X>
|
||||
<nStopA2X>0</nStopA2X>
|
||||
</AfterMake>
|
||||
<SelectedForBatchBuild>0</SelectedForBatchBuild>
|
||||
<SVCSIdString></SVCSIdString>
|
||||
</TargetCommonOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>0</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>0</AlwaysBuild>
|
||||
<GenerateAssemblyFile>0</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
<SimDllName>SARMCM3.DLL</SimDllName>
|
||||
<SimDllArguments> -REMAP -MPU</SimDllArguments>
|
||||
<SimDlgDll>DCM.DLL</SimDlgDll>
|
||||
<SimDlgDllArguments>-pCM4</SimDlgDllArguments>
|
||||
<TargetDllName>SARMCM3.DLL</TargetDllName>
|
||||
<TargetDllArguments> -MPU</TargetDllArguments>
|
||||
<TargetDlgDll>TCM.DLL</TargetDlgDll>
|
||||
<TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
|
||||
</DllOption>
|
||||
<DebugOption>
|
||||
<OPTHX>
|
||||
<HexSelection>1</HexSelection>
|
||||
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||
<HexOffset>0</HexOffset>
|
||||
<Oh166RecLen>16</Oh166RecLen>
|
||||
</OPTHX>
|
||||
</DebugOption>
|
||||
<Utilities>
|
||||
<Flash1>
|
||||
<UseTargetDll>1</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||
<Capability>1</Capability>
|
||||
<DriverSelection>4096</DriverSelection>
|
||||
</Flash1>
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
<pFcarmGrp></pFcarmGrp>
|
||||
<pFcArmRoot></pFcArmRoot>
|
||||
<FcArmLst>0</FcArmLst>
|
||||
</Utilities>
|
||||
<TargetArmAds>
|
||||
<ArmAdsMisc>
|
||||
<GenerateListings>0</GenerateListings>
|
||||
<asHll>1</asHll>
|
||||
<asAsm>1</asAsm>
|
||||
<asMacX>1</asMacX>
|
||||
<asSyms>1</asSyms>
|
||||
<asFals>1</asFals>
|
||||
<asDbgD>1</asDbgD>
|
||||
<asForm>1</asForm>
|
||||
<ldLst>0</ldLst>
|
||||
<ldmm>1</ldmm>
|
||||
<ldXref>1</ldXref>
|
||||
<BigEnd>0</BigEnd>
|
||||
<AdsALst>1</AdsALst>
|
||||
<AdsACrf>1</AdsACrf>
|
||||
<AdsANop>0</AdsANop>
|
||||
<AdsANot>0</AdsANot>
|
||||
<AdsLLst>1</AdsLLst>
|
||||
<AdsLmap>1</AdsLmap>
|
||||
<AdsLcgr>1</AdsLcgr>
|
||||
<AdsLsym>1</AdsLsym>
|
||||
<AdsLszi>1</AdsLszi>
|
||||
<AdsLtoi>1</AdsLtoi>
|
||||
<AdsLsun>1</AdsLsun>
|
||||
<AdsLven>1</AdsLven>
|
||||
<AdsLsxf>1</AdsLsxf>
|
||||
<RvctClst>0</RvctClst>
|
||||
<GenPPlst>0</GenPPlst>
|
||||
<AdsCpuType>"Cortex-M4"</AdsCpuType>
|
||||
<RvctDeviceName></RvctDeviceName>
|
||||
<mOS>0</mOS>
|
||||
<uocRom>0</uocRom>
|
||||
<uocRam>0</uocRam>
|
||||
<hadIROM>1</hadIROM>
|
||||
<hadIRAM>1</hadIRAM>
|
||||
<hadXRAM>0</hadXRAM>
|
||||
<uocXRam>0</uocXRam>
|
||||
<RvdsVP>2</RvdsVP>
|
||||
<RvdsMve>0</RvdsMve>
|
||||
<RvdsCdeCp>0</RvdsCdeCp>
|
||||
<hadIRAM2>0</hadIRAM2>
|
||||
<hadIROM2>0</hadIROM2>
|
||||
<StupSel>8</StupSel>
|
||||
<useUlib>0</useUlib>
|
||||
<EndSel>0</EndSel>
|
||||
<uLtcg>0</uLtcg>
|
||||
<nSecure>0</nSecure>
|
||||
<RoSelD>3</RoSelD>
|
||||
<RwSelD>3</RwSelD>
|
||||
<CodeSel>0</CodeSel>
|
||||
<OptFeed>0</OptFeed>
|
||||
<NoZi1>0</NoZi1>
|
||||
<NoZi2>0</NoZi2>
|
||||
<NoZi3>0</NoZi3>
|
||||
<NoZi4>0</NoZi4>
|
||||
<NoZi5>0</NoZi5>
|
||||
<Ro1Chk>0</Ro1Chk>
|
||||
<Ro2Chk>0</Ro2Chk>
|
||||
<Ro3Chk>0</Ro3Chk>
|
||||
<Ir1Chk>1</Ir1Chk>
|
||||
<Ir2Chk>0</Ir2Chk>
|
||||
<Ra1Chk>0</Ra1Chk>
|
||||
<Ra2Chk>0</Ra2Chk>
|
||||
<Ra3Chk>0</Ra3Chk>
|
||||
<Im1Chk>1</Im1Chk>
|
||||
<Im2Chk>0</Im2Chk>
|
||||
<OnChipMemories>
|
||||
<Ocm1>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm1>
|
||||
<Ocm2>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm2>
|
||||
<Ocm3>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm3>
|
||||
<Ocm4>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm4>
|
||||
<Ocm5>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm5>
|
||||
<Ocm6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm6>
|
||||
<IRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x18000</Size>
|
||||
</IRAM>
|
||||
<IROM>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x80000</Size>
|
||||
</IROM>
|
||||
<XRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</XRAM>
|
||||
<OCR_RVCT1>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT1>
|
||||
<OCR_RVCT2>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT2>
|
||||
<OCR_RVCT3>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT3>
|
||||
<OCR_RVCT4>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x80000</Size>
|
||||
</OCR_RVCT4>
|
||||
<OCR_RVCT5>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT5>
|
||||
<OCR_RVCT6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT6>
|
||||
<OCR_RVCT7>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT7>
|
||||
<OCR_RVCT8>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT8>
|
||||
<OCR_RVCT9>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x18000</Size>
|
||||
</OCR_RVCT9>
|
||||
<OCR_RVCT10>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT10>
|
||||
</OnChipMemories>
|
||||
<RvctStartVector></RvctStartVector>
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>1</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
<Strict>0</Strict>
|
||||
<EnumInt>0</EnumInt>
|
||||
<PlainCh>1</PlainCh>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<wLevel>2</wLevel>
|
||||
<uThumb>0</uThumb>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<uC99>1</uC99>
|
||||
<uGnu>0</uGnu>
|
||||
<useXO>0</useXO>
|
||||
<v6Lang>3</v6Lang>
|
||||
<v6LangP>3</v6LangP>
|
||||
<vShortEn>1</vShortEn>
|
||||
<vShortWch>1</vShortWch>
|
||||
<v6Lto>0</v6Lto>
|
||||
<v6WtE>0</v6WtE>
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>__STDC_LIMIT_MACROS</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..\include;..\ArmTimerCallbacks - C++</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>1</interw>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<thumb>0</thumb>
|
||||
<SplitLS>0</SplitLS>
|
||||
<SwStkChk>0</SwStkChk>
|
||||
<NoWarn>0</NoWarn>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<useXO>0</useXO>
|
||||
<ClangAsOpt>4</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
<LDads>
|
||||
<umfTarg>0</umfTarg>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<noStLib>0</noStLib>
|
||||
<RepFail>1</RepFail>
|
||||
<useFile>0</useFile>
|
||||
<TextAddressRange>0x08000000</TextAddressRange>
|
||||
<DataAddressRange>0x20000000</DataAddressRange>
|
||||
<pXoBase></pXoBase>
|
||||
<ScatterFile></ScatterFile>
|
||||
<IncludeLibs></IncludeLibs>
|
||||
<IncludeLibsPath></IncludeLibsPath>
|
||||
<Misc></Misc>
|
||||
<LinkerInputFile></LinkerInputFile>
|
||||
<DisabledWarnings></DisabledWarnings>
|
||||
</LDads>
|
||||
</TargetArmAds>
|
||||
</TargetOption>
|
||||
<Groups>
|
||||
<Group>
|
||||
<GroupName>Source Group 1</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>main.cpp</FileName>
|
||||
<FileType>8</FileType>
|
||||
<FilePath>.\main.cpp</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>etl_profile.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>.\etl_profile.h</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::Board Support</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::Device</GroupName>
|
||||
</Group>
|
||||
</Groups>
|
||||
</Target>
|
||||
</Targets>
|
||||
|
||||
<RTE>
|
||||
<apis>
|
||||
<api Capiversion="1.0.0" Cclass="Board Support" Cgroup="Buttons" exclusive="0">
|
||||
<package name="MDK-Middleware" schemaVersion="1.4" url="http://www.keil.com/pack/" vendor="Keil" version="7.4.1"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</api>
|
||||
<api Capiversion="1.0.0" Cclass="Board Support" Cgroup="LED" exclusive="0">
|
||||
<package name="MDK-Middleware" schemaVersion="1.4" url="http://www.keil.com/pack/" vendor="Keil" version="7.4.1"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</api>
|
||||
</apis>
|
||||
<components>
|
||||
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.4.0" condition="ARMv6_7_8-M Device">
|
||||
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.7.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
<component Capiversion="1.00" Cbundle="NUCLEO-F401RE" Cclass="Board Support" Cgroup="Buttons" Cvendor="Keil" Cversion="1.1.0" condition="F401RE CMSIS Device">
|
||||
<package name="STM32NUCLEO_BSP" schemaVersion="1.2" url="http://www.keil.com/pack/" vendor="Keil" version="1.6.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
<component Capiversion="1.00" Cbundle="NUCLEO-F401RE" Cclass="Board Support" Cgroup="LED" Cvendor="Keil" Cversion="1.1.0" condition="F401RE CMSIS Device">
|
||||
<package name="STM32NUCLEO_BSP" schemaVersion="1.2" url="http://www.keil.com/pack/" vendor="Keil" version="1.6.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
<component Cclass="Device" Cgroup="Startup" Cvendor="Keil" Cversion="2.6.3" condition="STM32F4 CMSIS">
|
||||
<package name="STM32F4xx_DFP" schemaVersion="1.6.3" url="http://www.keil.com/pack/" vendor="Keil" version="2.15.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
</components>
|
||||
<files>
|
||||
<file attr="config" category="source" condition="STM32F401xE_ARMCC" name="Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm\startup_stm32f401xe.s" version="2.6.0">
|
||||
<instance index="0">RTE\Device\STM32F401RETx\startup_stm32f401xe.s</instance>
|
||||
<component Cclass="Device" Cgroup="Startup" Cvendor="Keil" Cversion="2.6.3" condition="STM32F4 CMSIS"/>
|
||||
<package name="STM32F4xx_DFP" schemaVersion="1.6.3" url="http://www.keil.com/pack/" vendor="Keil" version="2.15.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</file>
|
||||
<file attr="config" category="source" name="Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c" version="2.6.0">
|
||||
<instance index="0">RTE\Device\STM32F401RETx\system_stm32f4xx.c</instance>
|
||||
<component Cclass="Device" Cgroup="Startup" Cvendor="Keil" Cversion="2.6.3" condition="STM32F4 CMSIS"/>
|
||||
<package name="STM32F4xx_DFP" schemaVersion="1.6.3" url="http://www.keil.com/pack/" vendor="Keil" version="2.15.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Target 1"/>
|
||||
</targetInfos>
|
||||
</file>
|
||||
</files>
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
<LayName><Project Info></LayName>
|
||||
<LayDesc></LayDesc>
|
||||
<LayUrl></LayUrl>
|
||||
<LayKeys></LayKeys>
|
||||
<LayCat></LayCat>
|
||||
<LayLic></LayLic>
|
||||
<LayTarg>0</LayTarg>
|
||||
<LayPrjMark>1</LayPrjMark>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef __ETL_PROFILE_H__
|
||||
#define __ETL_PROFILE_H__
|
||||
|
||||
#define ETL_VERBOSE_ERRORS
|
||||
#define ETL_CHECK_PUSH_POP
|
||||
#define ETL_ISTRING_REPAIR_ENABLE
|
||||
#define ETL_IVECTOR_REPAIR_ENABLE
|
||||
#define ETL_IDEQUE_REPAIR_ENABLE
|
||||
#define ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK
|
||||
#define ETL_NO_STL
|
||||
|
||||
//#include "etl/profiles/auto.h"
|
||||
|
||||
#endif
|
||||
167
Chapter17/cib/libs/etl/examples/ArmTimerCallbacks - C++/main.cpp
Normal file
167
Chapter17/cib/libs/etl/examples/ArmTimerCallbacks - C++/main.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
//#if (__cplusplus < 201103L)
|
||||
extern "C"
|
||||
{
|
||||
//#endif
|
||||
#include "Board_LED.h" // ::Board Support:LED
|
||||
#include "Board_Buttons.h" // ::Board Support:Buttons
|
||||
//#if (__cplusplus < 201103L)
|
||||
}
|
||||
//#endif
|
||||
|
||||
#include "stm32f4xx.h" // Device header
|
||||
|
||||
#include "etl/function.h"
|
||||
#include "etl/callback_timer.h"
|
||||
#include "etl/vector.h"
|
||||
#include "etl/iterator.h"
|
||||
#include "etl/binary.h"
|
||||
|
||||
struct FP
|
||||
{
|
||||
void (*function)();
|
||||
};
|
||||
|
||||
static etl::vector<FP, 10> power_callbacks;
|
||||
|
||||
void register_poweroff_callback(void (*function)())
|
||||
{
|
||||
FP fp = { function };
|
||||
power_callbacks.push_back(fp);
|
||||
}
|
||||
|
||||
const int N_TIMERS = 4;
|
||||
|
||||
etl::callback_timer<N_TIMERS> callback_timer;
|
||||
|
||||
etl::timer::id::type short_toggle;
|
||||
etl::timer::id::type long_toggle;
|
||||
etl::timer::id::type start_timers;
|
||||
etl::timer::id::type swap_timers;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* SystemCoreClockConfigure: configure SystemCoreClock using HSI
|
||||
(HSE is not populated on Nucleo board)
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockConfigure(void) {
|
||||
|
||||
RCC->CR |= ((uint32_t)RCC_CR_HSION); // Enable HSI
|
||||
while ((RCC->CR & RCC_CR_HSIRDY) == 0); // Wait for HSI Ready
|
||||
|
||||
RCC->CFGR = RCC_CFGR_SW_HSI; // HSI is system clock
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Wait for HSI used as system clock
|
||||
|
||||
FLASH->ACR = FLASH_ACR_PRFTEN; // Enable Prefetch Buffer
|
||||
FLASH->ACR |= FLASH_ACR_ICEN; // Instruction cache enable
|
||||
FLASH->ACR |= FLASH_ACR_DCEN; // Data cache enable
|
||||
FLASH->ACR |= FLASH_ACR_LATENCY_5WS; // Flash 5 wait state
|
||||
|
||||
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // HCLK = SYSCLK
|
||||
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; // APB1 = HCLK/4
|
||||
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; // APB2 = HCLK/2
|
||||
|
||||
RCC->CR &= ~RCC_CR_PLLON; // Disable PLL
|
||||
|
||||
// PLL configuration: VCO = HSI/M * N, Sysclk = VCO/P
|
||||
RCC->PLLCFGR = ( 16ul | // PLL_M = 16
|
||||
(384ul << 6U) | // PLL_N = 384
|
||||
( 3ul << 16U) | // PLL_P = 8
|
||||
(RCC_PLLCFGR_PLLSRC_HSI) | // PLL_SRC = HSI
|
||||
( 8ul << 24U) ); // PLL_Q = 8
|
||||
|
||||
RCC->CR |= RCC_CR_PLLON; // Enable PLL
|
||||
while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); // Wait till PLL is ready
|
||||
|
||||
RCC->CFGR &= ~RCC_CFGR_SW; // Select PLL as system clock source
|
||||
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait till PLL is system clock src
|
||||
}
|
||||
|
||||
void StartTimers()
|
||||
{
|
||||
callback_timer.start(short_toggle);
|
||||
callback_timer.start(swap_timers);
|
||||
}
|
||||
|
||||
void SwapTimers()
|
||||
{
|
||||
static bool state = false;
|
||||
|
||||
if (!state)
|
||||
{
|
||||
callback_timer.stop(short_toggle);
|
||||
callback_timer.start(long_toggle);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback_timer.start(short_toggle);
|
||||
callback_timer.stop(long_toggle);
|
||||
}
|
||||
|
||||
state = !state;
|
||||
|
||||
callback_timer.start(swap_timers);
|
||||
}
|
||||
|
||||
void LedToggle()
|
||||
{
|
||||
static bool state = false;
|
||||
|
||||
if (state)
|
||||
{
|
||||
LED_On(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LED_Off(0);
|
||||
}
|
||||
|
||||
state = !state;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SystemCoreClockConfigure(); // configure HSI as System Clock
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
LED_Initialize();
|
||||
Buttons_Initialize();
|
||||
|
||||
// The LEDs will start flashing fast after 2 seconds.
|
||||
// After another 5 seconds they will start flashing slower.
|
||||
short_toggle = callback_timer.register_timer(LedToggle, 50, etl::timer::mode::REPEATING);
|
||||
long_toggle = callback_timer.register_timer(LedToggle, 100, etl::timer::mode::REPEATING);
|
||||
start_timers = callback_timer.register_timer(StartTimers, 2000, etl::timer::mode::SINGLE_SHOT);
|
||||
swap_timers = callback_timer.register_timer(SwapTimers, 1500, etl::timer::mode::SINGLE_SHOT);
|
||||
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
callback_timer.enable(true);
|
||||
|
||||
callback_timer.start(start_timers);
|
||||
|
||||
while (true)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void SysTick_Handler()
|
||||
{
|
||||
const uint32_t TICK = 1U;
|
||||
static uint32_t nticks = TICK;
|
||||
|
||||
if (callback_timer.tick(nticks))
|
||||
{
|
||||
nticks = TICK;
|
||||
}
|
||||
else
|
||||
{
|
||||
nticks += TICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Chapter17/cib/libs/etl/examples/Blink/Blink1/__vm/.gitignore
vendored
Normal file
2
Chapter17/cib/libs/etl/examples/Blink/Blink1/__vm/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.vsarduino.h
|
||||
*.vmps.xml
|
||||
53
Chapter17/cib/libs/etl/examples/BlinkList/BlinkList.ino
Normal file
53
Chapter17/cib/libs/etl/examples/BlinkList/BlinkList.ino
Normal file
@@ -0,0 +1,53 @@
|
||||
//***********************************************************************************
|
||||
// A version of the Blink demo, but with delays stored in two instances of etl::list
|
||||
//***********************************************************************************
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <list.h>
|
||||
#include <container.h>
|
||||
|
||||
void setup()
|
||||
{
|
||||
// initialize digital pin 13 as an output.
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
void iterate(const etl::ilist<int>& delays)
|
||||
{
|
||||
etl::ilist<int>::const_iterator itr;
|
||||
|
||||
// Iterate through the list.
|
||||
itr = delays.begin();
|
||||
|
||||
while (itr != delays.end())
|
||||
{
|
||||
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
|
||||
delay(100); // wait
|
||||
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
|
||||
delay(*itr++); // wait
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int delay_times1[] = { 900, 800, 700, 600, 500, 400, 300, 200, 100 };
|
||||
int delay_times2[] = { 400, 300, 200, 100 };
|
||||
|
||||
// Fill the first delay list, then reverse it.
|
||||
// Notice how we don't have to know the size of the array!
|
||||
const size_t size1 = sizeof(etl::array_size(delay_times1));
|
||||
etl::list<int, size1> delays1(etl::begin(delay_times1), etl::end(delay_times1));
|
||||
delays1.reverse();
|
||||
|
||||
// Fill the second delay list,
|
||||
const size_t size2 = sizeof(etl::array_size(delay_times2));
|
||||
etl::list<int, size2> delays2(etl::begin(delay_times2), etl::end(delay_times2));
|
||||
|
||||
while (true)
|
||||
{
|
||||
iterate(delays1);
|
||||
iterate(delays2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlinkList", "BlinkList.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\BlinkList.ino" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="__vm\.VisualMicro.vsarduino.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="__vm\.BlinkList.vsarduino.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
1
Chapter17/cib/libs/etl/examples/BlinkList/VisualMicro/__vm/.gitignore
vendored
Normal file
1
Chapter17/cib/libs/etl/examples/BlinkList/VisualMicro/__vm/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.vsarduino.h
|
||||
1
Chapter17/cib/libs/etl/examples/BlinkList/__vm/.gitignore
vendored
Normal file
1
Chapter17/cib/libs/etl/examples/BlinkList/__vm/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.vmps.xml
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user