|
JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
|
Compile-time deduction of collectable containers — determining whether and how a container C can accept elements of a range R through incremental, value-preserving insertion.
More...
#include <cstdint>#include "jh/conceptual/closable_container.h"#include "jh/conceptual/tuple_like.h"Go to the source code of this file.
Namespaces | |
| namespace | jh::concepts |
| Behavioral concept namespace of the JH Toolkit. | |
Concepts | |
| concept | jh::concepts::collectable_container_for |
Concept verifying that a container C can collect elements from a range R via incremental insertion. | |
Compile-time deduction of collectable containers — determining whether and how a container C can accept elements of a range R through incremental, value-preserving insertion.
This header defines the collectable container model, which forms the foundation of jh::ranges::collect. It classifies all containers that can materialize data from a range using well-defined insertion semantics, possibly including tuple-like structural unpacking.
A container is collectable from a range when it can be incrementally populated with the elements of that range, without requiring any external constructor arguments. This mechanism powers jh::ranges::collect, which performs data materialization and normalization — converting a lazy or proxy-based pipeline into a concrete, value-semantic container.
In contrast, jh::ranges::to performs container adaptation: it builds the final target container, possibly with allocators, hashers, or custom constructor parameters. Therefore:
collect has no extra arguments; it only materializes and normalizes data. to may take constructor arguments and performs the final adaptation step. collect + to forms a complete materialization → adaptation pipeline. The collectable_status enumeration defines all supported behaviors:
closable — the container is directly constructible via jh::ranges::to. emplace_back_direct — appends elements using emplace_back(). push_back_direct — appends using push_back(). emplace_direct — inserts at logical end using emplace(). insert_direct — inserts at logical end using insert(). emplace_back_unpack — performs tuple-like structural unpacking into emplace_back(). emplace_unpack — performs tuple-like structural unpacking into emplace(). emplace_back, push_back, emplace, insert) exactly correspond to the element-wise insertion semantics defined for std::ranges::to, ensuring identical behavior in the incremental case. collect can destructure tuple-like elements (with std::tuple_size, std::tuple_element, and ADL get()) and reconstruct real value objects directly in-place. Unpacking requires the element type to be an explicitly tuple-like type, providing all of:
std::tuple_size<T> std::tuple_element<I, T> get<I>(T) Arbitrary aggregates or user-defined proxies are not implicitly unpacked, ensuring deterministic behavior and preserving the element's semantic identity.
jh::ranges::collect — uses this classification to materialize non-closable ranges into stable containers. jh::ranges::to — skips this classification entirely, performing direct container construction when closable. jh::concepts::closable_container_for — represents the complementary "construction-level" concept for to. The collectable_container_for concept ensures that collect can safely and deterministically construct a container C from a range R via incremental insertion, matching the observable semantics of std::ranges::to while supporting richer tuple-unpacking behaviors.
collect is a materializer, not an adaptor: it normalizes and realizes data into value semantics, but never applies construction arguments. Configuration belongs exclusively to to, allowing collect + to to form a clean, composable, two-stage pipeline.1.3.x
2025