rename chapters
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user