Skip to content

<xstd/misc/concepts/specialization_of.hpp>

xstd::specialization_of

template<class T, template<class...> class Primary>
concept specialization_of = is_specialization_of_v<remove_const_t<T>, Primary>;

A specialization of the class template Primary, whose parameters are all types, const or not.

Models

  • A specialization of Primary models it, and so does that specialization const.
  • A reference to a specialization does not.
  • An adaptor constrained on it accepts a const owner and a mutable one.

Example

#include <xstd/misc/concepts/specialization_of.hpp> // specialization_of
#include <deque>                                    // deque
#include <iostream>                                 // boolalpha, cout
#include <vector>                                   // vector

// A view of the last element of any std::vector, which may be const: the owner's type names its constness.
template<xstd::specialization_of<std::vector> Owner>
class back_view
{
        Owner* m_owner;

public:
        [[nodiscard]] constexpr explicit back_view(Owner& owner) noexcept
                : m_owner(&owner)
        {}

        [[nodiscard]] constexpr auto get() const
                -> auto&
        {
                return m_owner->back();
        }
};

template<class Owner>
back_view(Owner&) -> back_view<Owner>;

auto main() -> int
{
        auto numbers       = std::vector<int>{1, 2, 3};
        auto const letters = std::vector<char>{'a', 'b', 'c'};

        back_view(numbers).get() = 4;
        std::cout << numbers.back() << ' ' << back_view(letters).get() << '\n';

        std::cout << std::boolalpha;
        std::cout << "specialization_of<std::vector<int>, std::vector> is " << xstd::specialization_of<std::vector<int>, std::vector> << '\n';
        std::cout << "specialization_of<std::vector<int> const, std::vector> is " << xstd::specialization_of<std::vector<int> const, std::vector> << '\n';
        std::cout << "specialization_of<std::vector<int>&, std::vector> is " << xstd::specialization_of<std::vector<int>&, std::vector> << '\n';
        std::cout << "specialization_of<std::deque<int>, std::vector> is " << xstd::specialization_of<std::deque<int>, std::vector> << '\n';
}

Output:

4 c
specialization_of<std::vector<int>, std::vector> is true
specialization_of<std::vector<int> const, std::vector> is true
specialization_of<std::vector<int>&, std::vector> is false
specialization_of<std::deque<int>, std::vector> is false

See also

Entity Relation
is_specialization_of the exact trait it reads, for which a const specialization is not one