AimRT/install_x64/include/unifex/std_concepts.hpp
2025-01-12 19:51:34 +08:00

295 lines
8.7 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <unifex/detail/concept_macros.hpp>
#include <unifex/swap.hpp>
#include <unifex/type_traits.hpp>
#include <functional>
#include <type_traits>
#include <unifex/detail/prologue.hpp>
namespace unifex {
template <typename A, typename B>
UNIFEX_CONCEPT
same_as =
UNIFEX_IS_SAME(A, B) &&
UNIFEX_IS_SAME(B, A);
template <typename From, typename To>
UNIFEX_CONCEPT_FRAGMENT(
_explicitly_convertible_to,
requires(From(*from)()) //
(
static_cast<To>(from())
));
template <typename From, typename To>
UNIFEX_CONCEPT
convertible_to =
std::is_convertible_v<std::add_rvalue_reference_t<From>, To> &&
UNIFEX_FRAGMENT(unifex::_explicitly_convertible_to, From, To);
/// \cond
namespace detail {
template <typename T>
using _cref_t = std::remove_reference_t<T> const &;
template <class T>
UNIFEX_CONCEPT_FRAGMENT(
_boolean_testable_impl,
requires(T && t)
(
requires(convertible_to<decltype(! (T &&) t), bool>)
));
template <class T>
UNIFEX_CONCEPT
_boolean_testable =
UNIFEX_FRAGMENT(_boolean_testable_impl, T) &&
convertible_to<T, bool>;
UNIFEX_DIAGNOSTIC_PUSH
UNIFEX_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
template <typename T, typename U>
UNIFEX_CONCEPT_FRAGMENT(
_weakly_equality_comparable_with,
requires(_cref_t<T> t, _cref_t<U> u) //
(
requires(_boolean_testable<decltype(t == u)>),
requires(_boolean_testable<decltype(t != u)>),
requires(_boolean_testable<decltype(u == t)>),
requires(_boolean_testable<decltype(u != t)>)
));
template <typename T, typename U>
UNIFEX_CONCEPT
weakly_equality_comparable_with_ =
UNIFEX_FRAGMENT(detail::_weakly_equality_comparable_with, T, U);
UNIFEX_DIAGNOSTIC_POP
} // namespace detail
/// \endcond
template <typename T, typename U>
UNIFEX_CONCEPT_FRAGMENT(
_derived_from,
requires()(0) &&
convertible_to<T const volatile *, U const volatile *>);
template <typename T, typename U>
UNIFEX_CONCEPT
derived_from =
UNIFEX_IS_BASE_OF(U, T) &&
UNIFEX_FRAGMENT(unifex::_derived_from, T, U);
template <typename T, typename U>
UNIFEX_CONCEPT_FRAGMENT(
_assignable_from,
requires(T t, U && u) //
(
t = (U &&) u,
requires(same_as<T, decltype(t = (U &&) u)>)
));
template <typename T, typename U>
UNIFEX_CONCEPT
assignable_from =
std::is_lvalue_reference_v<T> &&
UNIFEX_FRAGMENT(unifex::_assignable_from, T, U);
template <typename T>
UNIFEX_CONCEPT_FRAGMENT(
_swappable,
requires(T & t, T & u) //
(
unifex::swap(t, u)
));
template <typename T>
UNIFEX_CONCEPT
swappable =
UNIFEX_FRAGMENT(unifex::_swappable, T);
template <typename T, typename U>
UNIFEX_CONCEPT_FRAGMENT(
_swappable_with,
requires(T && t, U && u) //
(
unifex::swap((T &&) t, (T &&) t),
unifex::swap((U &&) u, (U &&) u),
unifex::swap((U &&) u, (T &&) t),
unifex::swap((T &&) t, (U &&) u)
));
template <typename T, typename U>
UNIFEX_CONCEPT
swappable_with =
//common_reference_with<detail::_cref_t<T>, detail::_cref_t<U>> &&
UNIFEX_FRAGMENT(unifex::_swappable_with, T, U);
////////////////////////////////////////////////////////////////////////////////////////////
// Comparison concepts
////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
UNIFEX_CONCEPT
equality_comparable =
detail::weakly_equality_comparable_with_<T, T>;
// template <typename T, typename U>
// UNIFEX_CONCEPT_FRAGMENT(
// _equality_comparable_with,
// requires()(0) &&
// equality_comparable<
// common_reference_t<detail::_cref_t<T>, detail::_cref_t<U>>>);
template <typename T, typename U>
UNIFEX_CONCEPT
equality_comparable_with =
equality_comparable<T> &&
equality_comparable<U> &&
detail::weakly_equality_comparable_with_<T, U>;// &&
//common_reference_with<detail::_cref_t<T>, detail::_cref_t<U>> &&
//UNIFEX_FRAGMENT(unifex::_equality_comparable_with, T, U);
template <typename T>
UNIFEX_CONCEPT_FRAGMENT(
_totally_ordered,
requires(detail::_cref_t<T> t, detail::_cref_t<T> u) //
(
requires(detail::_boolean_testable<decltype(t < u)>),
requires(detail::_boolean_testable<decltype(t > u)>),
requires(detail::_boolean_testable<decltype(u <= t)>),
requires(detail::_boolean_testable<decltype(u >= t)>)
));
template <typename T>
UNIFEX_CONCEPT
totally_ordered =
equality_comparable<T> &&
UNIFEX_FRAGMENT(unifex::_totally_ordered, T);
template <typename T, typename U>
UNIFEX_CONCEPT_FRAGMENT(
_totally_ordered_with,
requires(detail::_cref_t<T> t, detail::_cref_t<U> u) //
(
requires(detail::_boolean_testable<decltype(t < u)>),
requires(detail::_boolean_testable<decltype(t > u)>),
requires(detail::_boolean_testable<decltype(t <= u)>),
requires(detail::_boolean_testable<decltype(t >= u)>),
requires(detail::_boolean_testable<decltype(u < t)>),
requires(detail::_boolean_testable<decltype(u > t)>),
requires(detail::_boolean_testable<decltype(u <= t)>),
requires(detail::_boolean_testable<decltype(u >= t)>)
));
//&& totally_ordered<
// common_reference_t<detail::_cref_t<T>, detail::_cref_t<U>>>
template <typename T, typename U>
UNIFEX_CONCEPT
totally_ordered_with =
totally_ordered<T> &&
totally_ordered<U> &&
equality_comparable_with<T, U> &&
//common_reference_with<detail::_cref_t<T>, detail::_cref_t<U>> &&
UNIFEX_FRAGMENT(unifex::_totally_ordered_with, T, U);
////////////////////////////////////////////////////////////////////////////////////////////
// Object concepts
////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
UNIFEX_CONCEPT
destructible =
std::is_nothrow_destructible_v<T>;
template <typename T, typename... Args>
UNIFEX_CONCEPT
constructible_from =
destructible<T> &&
UNIFEX_IS_CONSTRUCTIBLE(T, Args...);
template <typename T>
UNIFEX_CONCEPT
default_constructible =
constructible_from<T>;
template <typename T>
UNIFEX_CONCEPT
move_constructible =
constructible_from<T, T> &&
convertible_to<T, T>;
template <typename T>
UNIFEX_CONCEPT_FRAGMENT(
_copy_constructible,
requires()(0) &&
constructible_from<T, T &> &&
constructible_from<T, T const &> &&
constructible_from<T, T const> &&
convertible_to<T &, T> &&
convertible_to<T const &, T> &&
convertible_to<T const, T>);
template <typename T>
UNIFEX_CONCEPT
copy_constructible =
move_constructible<T> &&
UNIFEX_FRAGMENT(unifex::_copy_constructible, T);
template <typename T>
UNIFEX_CONCEPT_FRAGMENT(
_move_assignable,
requires()(0) &&
assignable_from<T &, T>);
template <typename T>
UNIFEX_CONCEPT
movable =
std::is_object_v<T> &&
move_constructible<T> &&
UNIFEX_FRAGMENT(unifex::_move_assignable, T) &&
swappable<T>;
template <typename T>
UNIFEX_CONCEPT_FRAGMENT(
_copy_assignable,
requires()(0) &&
assignable_from<T &, T const &>);
template <typename T>
UNIFEX_CONCEPT
copyable =
copy_constructible<T> &&
movable<T> &&
UNIFEX_FRAGMENT(unifex::_copy_assignable, T);
template <typename T>
UNIFEX_CONCEPT
semiregular =
copyable<T> &&
default_constructible<T>;
// Axiom: copies are independent. See Fundamentals of Generic Programming
// http://www.stepanovpapers.com/DeSt98.pdf
template <typename T>
UNIFEX_CONCEPT
regular =
semiregular<T> &&
equality_comparable<T>;
template <typename Fn, typename... As>
UNIFEX_CONCEPT //
invocable = //
std::is_invocable_v<Fn, As...>;
} // namespace unifex
#include <unifex/detail/epilogue.hpp>