Internal concept that matches “empty‐clear default‐constructible” types.

Synopsis

Declared in <mrdocs/ADT/Nullable.hpp>

template<class T>
concept ClearableContainerLike = requires {
        typename T::value_type;
        typename T::size_type;
        typename T::difference_type;
        typename T::reference;
        typename T::const_reference;
        typename T::iterator;
        typename T::const_iterator;
    } &&
    // size_type should be integral for normal containers
    std::is_integral_v<typename T::size_type> &&

    // ‐‐‐‐ member begin/end with expected iterator types ‐‐‐‐
    requires(T& t, const T& ct) {
        { t.begin() }  ‐> std::convertible_to<typename T::iterator>;
        { t.end() }    ‐> std::convertible_to<typename T::iterator>;
        { ct.begin() } ‐> std::convertible_to<typename T::const_iterator>;
        { ct.end() }   ‐> std::convertible_to<typename T::const_iterator>;
    } &&

    // ‐‐‐‐ iterator “shape”: deref and increment ‐‐‐‐
    requires(T& t, const T& ct) {
        { *t.begin() }  ‐> std::convertible_to<typename T::reference>;
        { *ct.begin() } ‐> std::convertible_to<typename T::const_reference>;
        { ++std::declval<typename T::iterator&>() } ‐> std::same_as<typename T::iterator&>;
    } &&

    // ‐‐‐‐ size/empty/clear trio ‐‐‐‐
    requires(T& t, const T& ct) {
        { ct.size() }  ‐> std::same_as<typename T::size_type>;
        { ct.empty() } ‐> std::convertible_to<bool>;
        { t.clear() }  ‐> std::same_as<void>;
    } &&

    // ‐‐‐‐ default constructible (most std containers satisfy this) ‐‐‐‐
    std::default_initializable<T>;

Description

This captures the common case of containers and data structures that can be default‐constructed to empty, tested with .empty(), and reset with .clear().

Common cases of such containers include std::string, std::vector, std::optional, std::unique_ptr, std::shared_ptr, and many more.

Created with MrDocs