2022-03-18 12:38:30 +11:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <iterator>
|
|
|
|
#include <concepts>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// C++ named requirements
|
|
|
|
namespace cruft::concepts::named {
|
|
|
|
/// Corresponds to the "Container" named requirement.
|
|
|
|
template <class T>
|
|
|
|
concept container =
|
|
|
|
std::default_initializable<T> and
|
|
|
|
std::copy_constructible<T> and
|
|
|
|
std::move_constructible<T> and
|
|
|
|
std::destructible<T> and
|
|
|
|
std::equality_comparable<T> and
|
|
|
|
requires (T a, T b)
|
|
|
|
{
|
|
|
|
typename T::value_type;
|
|
|
|
typename T::reference;
|
|
|
|
typename T::const_reference;
|
|
|
|
typename T::iterator;
|
|
|
|
typename T::const_iterator;
|
|
|
|
typename T::difference_type;
|
|
|
|
typename T::size_type;
|
|
|
|
|
|
|
|
{ a = b } -> std::same_as<T&>;
|
|
|
|
{ a = std::move (b) } -> std::same_as<T&>;
|
|
|
|
|
|
|
|
{ a.begin () } -> std::same_as<typename T::iterator>;
|
|
|
|
{ a.end () } -> std::same_as<typename T::iterator>;
|
|
|
|
{ a.cbegin () } -> std::same_as<typename T::const_iterator>;
|
|
|
|
{ a.cend () } -> std::same_as<typename T::const_iterator>;
|
|
|
|
|
|
|
|
{ a.swap (b) } -> std::same_as<void>;
|
|
|
|
{ std::swap (a, b) } -> std::same_as<void>;
|
|
|
|
|
|
|
|
{ a.size () } -> std::same_as<typename T::size_type>;
|
|
|
|
{ a.max_size () } -> std::same_as<typename T::size_type>;
|
|
|
|
{ a.empty () } -> std::same_as<bool>;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
concept move_assignable =
|
|
|
|
requires (T a, T b)
|
|
|
|
{
|
|
|
|
{ a = std::move (b) } -> std::same_as<T&>;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
concept copy_assignable =
|
|
|
|
move_assignable<T> &&
|
|
|
|
requires (T a, T b)
|
|
|
|
{
|
|
|
|
{ a = b } -> std::same_as<T&>;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
concept legacy_iterator =
|
2024-08-10 14:18:08 +10:00
|
|
|
std::copy_constructible<T> &&
|
|
|
|
copy_assignable<T> &&
|
2022-03-18 12:38:30 +11:00
|
|
|
std::destructible<T> &&
|
2024-08-10 14:18:08 +10:00
|
|
|
std::swappable<T> &&
|
2022-03-18 12:38:30 +11:00
|
|
|
requires (T t)
|
|
|
|
{
|
|
|
|
typename std::iterator_traits<T>::value_type;
|
|
|
|
typename std::iterator_traits<T>::difference_type;
|
|
|
|
typename std::iterator_traits<T>::reference;
|
|
|
|
typename std::iterator_traits<T>::pointer;
|
|
|
|
typename std::iterator_traits<T>::iterator_category;
|
|
|
|
|
|
|
|
{ *t };
|
|
|
|
{ ++t } -> std::same_as<T&>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
concept legacy_input_iterator =
|
|
|
|
legacy_iterator<T> &&
|
|
|
|
std::equality_comparable<T> &&
|
|
|
|
requires (T a, T b)
|
|
|
|
{
|
|
|
|
typename std::iterator_traits<T>::reference;
|
|
|
|
typename std::iterator_traits<T>::value_type;
|
|
|
|
{ a != b } -> std::same_as<bool>;
|
|
|
|
|
|
|
|
{ ++a } -> std::same_as<T&>;
|
|
|
|
{ a++ };
|
|
|
|
};
|
|
|
|
}
|