rename chapters

This commit is contained in:
Amar Mahmutbegovic
2025-02-09 13:11:21 +01:00
parent 8634accda5
commit 526e6ec009
2928 changed files with 0 additions and 0 deletions

View 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

View 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

View 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

View 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>

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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