C++20 header-only library. Part of the ScL Toolkit.
ScL.Feature provides scl::wrapper<Value, Executors...> — a composable proxy wrapper that
delegates method calls to the held value through a chain of executor templates. Each executor
can transparently add cross-cutting behaviour such as copy-on-write semantics, thread safety,
or deferred invocation without modifying the wrapped type. Licensed under The Unlicense.
scl::wrapper<Value, Executors...>, a composable proxy:
Value through a left-folded executor chainfeature::inplace::plain when no executor is specifiedscl::feature::inplace):
inplace::plain — stores Value in-place with zero overhead; serves as the default executorinplace::uninitialized — holds Value in correctly sized and aligned raw storage,
enabling deferred (lazy) constructionscl::feature::wrapper_guard<Refer>:
guard() / unguard() on the executor at construction / destructionvalue() preserving the cv- and ref-qualifiers of the incoming referencescl::feature):
is_wrapper_v<T> — checks whether T is a wrapper specialization (strips cv-qualifiers)is_compatible_with_v<Expected, Test> — Test is the same as or derived from Expected;
for wrapper specialisations with the same executor the check is applied recursively to value typesis_compatible_with_part_of_v<Expected, Test> — Expected (a wrapper) recursively contains
a value compatible with Testis_part_compatible_with_v<Expected, Test> — Test (a wrapper) recursively contains
a value compatible with Expectedscl::feature::concepts):
concepts::wrapper<T> — satisfied when T is a wrapper specializationconcepts::compatible_with<Expected, T>concepts::compatible_with_part_of<Expected, T>concepts::part_compatible_with<Expected, T>scl/feature/reflection/):
SCL_REFLECT_TYPE(Type, Member) — declares the wrapper identity alias required by method reflectionSCL_REFLECT_METHOD(method) — generates 16 proxy overloads (8 cv-ref qualifications × 2:
deduced and explicit template arguments); each overload is constrained so only overloads
that actually exist on the wrapped type are exposedAdd the module as a subdirectory and link against the interface target:
add_subdirectory(module/feature)
target_link_libraries(your_target PRIVATE scl::feature)
#include <scl/feature/reflection/method.h>
#include <scl/feature/inplace/plain.h>
struct Target {
short get() &;
int get() const &;
float get() &&;
};
struct MyWrapper {
Executor<Target> m_executor; // any executor
SCL_REFLECT_TYPE(MyWrapper, m_executor);
SCL_REFLECT_METHOD(get) // generates 16 overloads, 3 survive constraints
};
MyWrapper w{42};
w.get(); // Target::get() & → short
std::as_const(w).get() // Target::get() const & → int
std::move(w).get(); // Target::get() && → float