Launch in T minus 10 seconds and counting...

This commit is contained in:
2026-06-04 03:08:51 +02:00
commit 048ac71f31
22 changed files with 648 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
# Generated version header.
#
version.hxx
# Unit test executables and Testscript output directories
# (can be symlinks).
#
*.test
test-*.test
+58
View File
@@ -0,0 +1,58 @@
intf_libs = # Interface dependencies.
impl_libs = # Implementation dependencies.
./: lib{framework}: libul{framework}
libul{framework}: {hxx ixx txx cxx}{** -**.test... -version} \
{hxx }{ version}
libul{framework}: $impl_libs $intf_libs
# Unit tests.
#
exe{*.test}:
{
test = true
install = false
}
for t: cxx{**.test...}
{
d = $directory($t)
n = $name($t)...
./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
$d/exe{$n}: libul{framework}: bin.whole = false
}
hxx{version}: in{version} $src_root/manifest
# Build options.
#
cxx.poptions =+ "-I$out_root" "-I$src_root"
# Export options.
#
lib{framework}:
{
cxx.export.poptions = "-I$out_root" "-I$src_root"
cxx.export.libs = $intf_libs
}
# For pre-releases use the complete version to make sure they cannot
# be used in place of another pre-release or the final version. See
# the version module for details on the version.* variable values.
#
if $version.pre_release
lib{framework}: bin.lib.version = "-$version.project_id"
else
lib{framework}: bin.lib.version = "-$version.major.$version.minor"
# Install into the framework/ subdirectory of, say, /usr/include/
# recreating subdirectories.
#
{hxx ixx txx}{*}:
{
install = include/framework/
install.subdirs = true
}
+304
View File
@@ -0,0 +1,304 @@
#ifndef framework__type_list_hxx_
#define framework__type_list_hxx_
#include <framework/types.hxx>
namespace framework
{
/// @brief Type list.
///
/// The type_list class serves two purposes. It functions as a template
/// meta-programming list of types (Ts) as well as a container of instances of
/// those types.
///
template<typename... Ts>
class type_list
{
public:
/// @brief Tag-dispatch type.
///
struct owning_t {};
/// @brief Tag for creating an owning type_list.
///
inline static constexpr owning_t owning{};
/// @brief Constructor.
///
/// This constructor creates an owning type list.
///
/// @param args The arguments passed to the constructor of the Ts.
///
///
template<typename... Args>
explicit
type_list(owning_t const&, Args&&... args)
: _data{make_unique<Ts>(std::forward<Args>(args)...)...}
{}
/// @brief Constructor.
///
/// This constructor makes a non-owning copy of @a other.
///
/// Once @a other is destroyed, this type list becomes invalidated.
///
type_list(type_list<Ts...>& other)
: _data{variant_type<Ts>{&other.template get<Ts>()}...}
{}
/// @brief Constructor.
///
/// This constructor makes a non-owning filtered copy of @a other.
///
/// Once @a other is destroyed, this type list becomes invalidated.
///
template<typename... Us>
type_list(type_list<Us...>& other)
: _data{variant_type<Ts>{&other.template get <Ts>()}...}
{}
/// @brief Constructor.
///
/// Moves @a other into this type list.
///
type_list(type_list<Ts...>&& other)
: _data{std::move(other._data)}
{}
/// @brief Get instance of type T held in this type list.
///
template<typename T>
T&
get()
{
auto& var = std::get<variant_type<T>>(_data);
return std::visit(
[](auto&& val) -> T&
{
return *val;
},
var
);
}
/// @brief Get instance of type T held in this type list.
///
template<typename T>
T const&
get() const
{
auto& var = std::get<variant_type<T>>(_data);
return std::visit(
[](auto&& val) -> T const&
{
return *val;
},
var
);
}
/// @brief Apply (invoke) function @a f passing all @a Ts and @a args.
///
template<typename F, typename... Args>
decltype(auto)
apply(F&& f, Args&&... args)
{
return f.template operator()<Ts...>(
get<Ts>()...,
std::forward<Args>(args)...
);
}
/// @brief Apply (invoke) function @a f passing all @a Ts and @a args.
///
template<typename F, typename... Args>
decltype(auto)
apply(F&& f, Args&&... args) const
{
return f.template operator()<Ts...>(
get<Ts>()...,
std::forward<Args>(args)...
);
}
/// @brief Apply (invoke) function @a f once for each @a Ts passing all @a
/// args.
///
template<typename F, typename... Args>
void
apply_for_each(F&& f, Args&&... args)
{
(
f.template operator()<Ts>(
get<Ts>(),
std::forward<Args>(args)...
),
...
);
}
/// @brief Apply (invoke) function @a f once for each @a Ts passing all @a
/// args.
///
template<typename F, typename... Args>
void
apply_for_each(F&& f, Args&&... args) const
{
(
f.template operator()<Ts>(
get<Ts>(),
std::forward<Args>(args)...
),
...
);
}
template<typename F, typename... Args>
static
decltype(auto)
apply_types(F&& f, Args&&... args)
{
return f.template operator()<Ts...>(
std::forward<Args>(args)...
);
}
template<typename F, typename... Args>
static
decltype(auto)
apply_types_for_each(F&& f, Args&&... args)
{
(
(
f.template operator()<Ts>(
std::forward<Args>(args)...
)
),
...
);
}
private:
/// @brief Variant type for either owning or borrowing type T.
///
template<typename T>
using variant_type = variant<unique_ptr<T>, T*>;
/// @brief Tuple type.
///
using tuple_type = tuple<variant_type<Ts>...>;
/// @brief Tuple holding instances of Ts.
///
tuple_type _data;
};
/// @brief Template to check if @a T is a type list.
///
template<typename>
struct is_type_list
: std::false_type
{};
template<typename... Ts>
struct is_type_list<type_list<Ts...>>
: std::true_type
{};
/// @brief Helper for is_type_list.
///
template<typename T>
inline constexpr bool const is_type_list_v = is_type_list<T>::value;
/// @brief Type list concept.
///
template<typename T>
concept TypeList = is_type_list_v<T>;
/// @brief Template to concatenate two or more type lists.
///
template<typename... Lists>
struct concat_type_list;
template<>
struct concat_type_list<>
{
using type = type_list<>;
};
template<typename... Ts>
struct concat_type_list<type_list<Ts...>>
{
using type = type_list<Ts...>;
};
template<typename... Ts, typename... Us, typename... Rest>
struct concat_type_list<
type_list<Ts...>,
type_list<Us...>,
Rest...
>
{
using type = typename concat_type_list<
type_list<Ts..., Us...>, Rest...
>::type;
};
/// @brief Helper for concat_type_list.
///
template<typename... Lists>
using concat_type_list_t = typename concat_type_list<Lists...>::type;
/// @brief Template to filter type list.
///
template<
template<typename> typename Predicate,
TypeList List
>
struct filter_type_list;
template<template<typename> typename Predicate, typename... Ts>
struct filter_type_list<Predicate, type_list<Ts...>>
{
using type = concat_type_list_t<
std::conditional_t<
Predicate<Ts>::value,
type_list<Ts>,
type_list<>
>...
>;
};
/// @brief Helper for filter_type_list.
///
template<template<typename> typename Predicate, typename List>
using filter_type_list_t = typename filter_type_list<Predicate, List>::type;
/// @brief Template to check if type T has T::deps and that T::deps is a
/// type list.
///
template<typename T, typename = void>
struct has_deps
: std::false_type
{};
template<typename T>
struct has_deps<T, std::void_t<typename T::deps>>
: std::integral_constant<
bool,
is_type_list_v<typename T::deps>
>
{};
/// @brief Helper for has_deps.
///
template<typename T>
inline constexpr bool const has_deps_v = has_deps<T>::value;
} // namespace framework
#endif
+41
View File
@@ -0,0 +1,41 @@
#ifndef framework__types_hxx_
#define framework__types_hxx_
#include <cstdint>
#include <memory>
#include <tuple>
#include <variant>
/// @brief Main namespace.
///
namespace framework
{
/// @brief Namespace with common types.
///
namespace types
{
using std::int8_t;
using std::int16_t;
using std::int32_t;
using std::int64_t;
using std::uint8_t;
using std::uint16_t;
using std::uint32_t;
using std::uint64_t;
using std::unique_ptr;
using std::make_unique;
using std::tuple;
using std::variant;
} // namespace types
using namespace types;
} // namespace framework
#endif
+37
View File
@@ -0,0 +1,37 @@
#ifndef framework__version_hxx_
#define framework__version_hxx_
// The numeric version format is AAAAABBBBBCCCCCDDDE where:
//
// AAAAA - major version number
// BBBBB - minor version number
// CCCCC - bugfix version number
// DDD - alpha / beta (DDD + 500) version number
// E - final (0) / snapshot (1)
//
// When DDDE is not 0, 1 is subtracted from AAAAABBBBBCCCCC. For example:
//
// Version AAAAABBBBBCCCCCDDDE
//
// 0.1.0 0000000001000000000
// 0.1.2 0000000001000020000
// 1.2.3 0000100002000030000
// 2.2.0-a.1 0000200001999990010
// 3.0.0-b.2 0000299999999995020
// 2.2.0-a.1.z 0000200001999990011
//
#define FRAMEWORK_VERSION $framework.version.project_number$ULL
#define FRAMEWORK_VERSION_STR "$framework.version.project$"
#define FRAMEWORK_VERSION_ID "$framework.version.project_id$"
#define FRAMEWORK_VERSION_FULL "$framework.version$"
#define FRAMEWORK_VERSION_MAJOR $framework.version.major$
#define FRAMEWORK_VERSION_MINOR $framework.version.minor$
#define FRAMEWORK_VERSION_PATCH $framework.version.patch$
#define FRAMEWORK_PRE_RELEASE $framework.version.pre_release$
#define FRAMEWORK_SNAPSHOT_SN $framework.version.snapshot_sn$ULL
#define FRAMEWORK_SNAPSHOT_ID "$framework.version.snapshot_id$"
#endif