basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | e5785277f51a5e5118eb00fd5b09b6785cfc0871 |
parent | 1ff25aa15525ef445c7e3c5716d83ae2a032d82f |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Wed, 7 May 2025 19:43:32 +0200 |
Bunch of traits and other functions
76 files changed, 1954 insertions(+), 927 deletions(-)
diff --git a/ .clang-tidy b/ .clang-tidy
@@ -18,6 +18,8 @@
Checks: "*,\
-modernize-use-trailing-return-type,\
-readability-suspicious-call-argument,\
-*-ranges,\
-cppcoreguidelines-missing-std-forward,\
-cppcoreguidelines-rvalue-reference-param-not-moved,\
"
WarningsAsErrors: ''
CheckOptions:
@@ -169,4 +171,8 @@
CheckOptions:
value: "u"
- key: 'google-runtime-int.SignedTypePrefix'
value: "i"
- key: 'cppcoreguidelines-missing-std-forward.ForwardFunction'
value: "::based::forward"
- key: 'cppcoreguidelines-rvalue-reference-param-not-moved.MoveFunction'
value: "::based::move"
...
diff --git a/ cmake/lint.cmake b/ cmake/lint.cmake
@@ -1,5 +1,12 @@
cmake_minimum_required(VERSION 3.14)
defaul(FORMAT_COMMAND clang-format)
macro(default name)
if(NOT DEFINED "${name}")
set("${name}" "${ARGN}")
endif()
endmacro()
default(FORMAT_COMMAND clang-format)
default(
PATTERNS
source/*.cpp source/*.hpp
diff --git a/ include/based/algorithms/max.hpp b/ include/based/algorithms/max.hpp
@@ -4,6 +4,7 @@
#include "based/concepts/is/same.hpp"
#include "based/concepts/procedure/procedure.hpp"
#include "based/trait/remove/reference.hpp"
#include "based/utility/forward.hpp"
namespace based
{
@@ -21,7 +22,7 @@
template<BareRegular T, BareRegular U, detail::NoninputRelation<T> Rel>
requires BareSameAs<T, U>
decltype(auto) max(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? std::forward<T>(lhs) : std::forward<U>(rhs);
return rel(rhs, lhs) ? based::forward<T>(lhs) : based::forward<U>(rhs);
}
// returns max element, second if equal
@@ -30,8 +31,8 @@
template<BareRegular T, BareRegular U>
decltype(auto) max(T&& lhs, U&& rhs)
{
return based::max(
std::forward<T>(lhs),
std::forward<U>(rhs),
based::forward<T>(lhs),
based::forward<U>(rhs),
[](const remove_reference_t<T>& llhs, const remove_reference_t<U>& lrhs)
{
return llhs < lrhs;
diff --git a/ include/based/algorithms/min.hpp b/ include/based/algorithms/min.hpp
@@ -4,6 +4,7 @@
#include "based/concepts/is/same.hpp"
#include "based/concepts/procedure/procedure.hpp"
#include "based/trait/remove/reference.hpp"
#include "based/utility/forward.hpp"
namespace based
{
@@ -20,7 +21,7 @@
template<BareRegular T, BareRegular U, detail::NoninputRelation<T> Rel>
requires BareSameAs<T, U>
decltype(auto) min(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? std::forward<U>(rhs) : std::forward<T>(lhs);
return rel(rhs, lhs) ? based::forward<U>(rhs) : based::forward<T>(lhs);
}
// returns min element, first if equal
@@ -29,8 +30,8 @@
template<BareRegular T, BareRegular U>
decltype(auto) min(T&& lhs, U&& rhs)
{
return based::min(
std::forward<T>(lhs),
std::forward<U>(rhs),
based::forward<T>(lhs),
based::forward<U>(rhs),
[](const remove_reference_t<T>& llhs, const remove_reference_t<U>& lrhs)
{
return llhs < lrhs;
diff --git a/ include/based/concepts/is/invocable.hpp b/ include/based/concepts/is/invocable.hpp
@@ -1,11 +1,11 @@
#pragma once
#include <concepts>
#include "based/trait/is/invocable.hpp"
namespace based
{
template<typename P, typename... Args>
concept Invocable = std::invocable<P, Args...>;
concept Invocable = is_invocable_v<P, Args...>;
} // namespace based
diff --git a/ include/based/enum/enum.hpp b/ include/based/enum/enum.hpp
@@ -4,6 +4,7 @@
#include <cassert>
#include "based/macros.hpp"
#include "based/utility/forward.hpp"
// NOLINTBEGIN(*macro-usage*)
@@ -67,7 +68,7 @@
requires(sizeof...(Args) == Name::type::size) \
constexpr explicit array(Args&&... args \
) noexcept /* NOLINTNEXTLINE(*decay*) */ \
: base({std::forward<Args>(args)...}) \
: base({based::forward<Args>(args)...}) \
{ \
} \
\
diff --git a/ include/based/functional/curry.hpp b/ include/based/functional/curry.hpp
@@ -2,6 +2,9 @@
#include <tuple>
#include "based/utility/forward.hpp"
#include "based/utility/move.hpp"
namespace based
{
@@ -16,14 +19,14 @@
class curried
curried(Function function, std::tuple<CapturedArgs...> args)
: m_function(function)
, m_captured(std::move(args))
, m_captured(based::move(args))
{
}
public:
curried(Function function, CapturedArgs&&... args) // NOLINT(*explicit*)
: m_function(function)
, m_captured(std::forward<CapturedArgs>(args)...)
, m_captured(based::forward<CapturedArgs>(args)...)
{
}
@@ -31,14 +34,14 @@
public:
auto operator()(NewArgs&&... args) const
{
auto all_args = std::tuple_cat(
m_captured, std::make_tuple(std::forward<NewArgs>(args)...)
m_captured, std::make_tuple(based::forward<NewArgs>(args)...)
);
if constexpr (std::is_invocable_v<Function, CapturedArgs..., NewArgs...>) {
return std::apply(m_function, std::move(all_args));
return std::apply(m_function, based::move(all_args));
} else {
return curried<Function, CapturedArgs..., NewArgs...> {
m_function, std::move(all_args)
m_function, based::move(all_args)
};
}
}
diff --git a/ include/based/functional/function.hpp b/ include/based/functional/function.hpp
@@ -6,6 +6,7 @@
#include "based/trait/signature.hpp"
#include "based/types/types.hpp"
#include "based/utility/buffer.hpp"
#include "based/utility/forward.hpp"
namespace based
{
@@ -38,7 +39,7 @@
class function<Ret(Args...), size, alignment>
{
return std::invoke(
*static_cast<function*>(func)->m_space.template as<Callable>(),
std::forward<Args>(args)...
based::forward<Args>(args)...
);
}
@@ -55,9 +56,7 @@
public:
})
function(CallableArg&& callable) // NOLINT(*explicit*)
: m_space(
std::in_place_type<Callable>, std::forward<CallableArg>(callable)
)
: m_space(std::in_place_type<Callable>, based::forward<CallableArg>(callable))
, m_executor(executor<Callable>)
{
}
@@ -66,7 +65,7 @@
public:
Ret operator()(CallArgs&&... callargs) const
{
return this->m_executor(
std::forward<CallArgs>(callargs)...,
based::forward<CallArgs>(callargs)...,
const_cast<function*>(this) // NOLINT(*const-cast*)
);
}
diff --git a/ include/based/functional/invoke.hpp b/ include/based/functional/invoke.hpp
@@ -0,0 +1,63 @@
#pragma once
#include "based/trait/is/base_of.hpp"
#include "based/trait/is/function.hpp"
#include "based/trait/is/invocable.hpp"
#include "based/trait/is/object.hpp"
#include "based/trait/is/reference_wrapper.hpp"
#include "based/utility/forward.hpp"
namespace based
{
namespace detail
{
template<class C, class Pointed, class Object, class... Args>
constexpr decltype(auto) invoke_memptr(
Pointed C::* member, Object&& object, Args&&... args
)
{
using object_t = remove_cvref_t<Object>;
constexpr bool is_member_function = is_function_v<Pointed>;
constexpr bool is_wrapped = is_reference_wrapper_v<object_t>;
constexpr bool is_derived_object =
is_same_v<C, object_t> || is_base_of_v<C, object_t>;
if constexpr (is_member_function) {
if constexpr (is_derived_object) {
return (based::forward<Object>(object).*member)(based::forward<Args>(args)...);
}
if constexpr (is_wrapped) {
return (object.get().*member)(based::forward<Args>(args)...);
}
return ((*based::forward<Object>(object)).*member)(based::forward<Args>(args)...);
} else {
static_assert(is_object_v<Pointed> && sizeof...(args) == 0);
if constexpr (is_derived_object) {
return based::forward<Object>(object).*member;
}
if constexpr (is_wrapped) {
return object.get().*member;
}
return (*based::forward<Object>(object)).*member;
}
}
} // namespace detail
template<class F, class... Args>
constexpr decltype(auto) invoke(
F&& func, Args&&... args
) noexcept(is_nothrow_invocable_v<F, Args...>)
{
if constexpr (is_member_pointer_v<remove_cvref_t<F>>) {
return detail::invoke_memptr(func, based::forward<Args>(args)...);
}
return based::forward<F>(func)(based::forward<Args>(args)...);
}
} // namespace based
diff --git a/ include/based/functional/reference_wrapper.hpp b/ include/based/functional/reference_wrapper.hpp
@@ -0,0 +1,73 @@
#pragma once
#include "based/memory/addressof.hpp"
#include "based/trait/is/invocable.hpp"
#include "based/trait/is/same.hpp"
#include "based/trait/remove/cvref.hpp"
#include "based/utility/declvar.hpp"
#include "based/utility/forward.hpp"
namespace based
{
namespace detail
{
// clang-format off
template<class T> constexpr T& fun(T& tmp) noexcept { return tmp; }
template<class T> void fun(T&&) = delete;
// clang-format on
} // namespace detail
template<class T>
class reference_wrapper
{
public:
// types
using type = T;
// construct/copy/destroy
template<class U>
requires(requires {
detail::fun<T>(declval<U>());
requires(!is_same_v<reference_wrapper, remove_cvref_t<U>>);
})
// NOLINTNEXTLINE(*explicit*)
constexpr reference_wrapper(U&& obj
) noexcept(noexcept(detail::fun<T>(based::forward<U>(obj))))
: m_ptr(addressof(detail::fun<T>(based::forward<U>(obj))))
{
}
reference_wrapper(const reference_wrapper&) noexcept = default;
reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
reference_wrapper(reference_wrapper&&) noexcept = delete;
reference_wrapper& operator=(reference_wrapper&& x) noexcept = delete;
~reference_wrapper() = default;
// NOLINTBEGIN(*explicit*)
constexpr operator T&() const noexcept { return *m_ptr; }
constexpr T& get() const noexcept { return *m_ptr; }
// NOLINTEND(*explicit*)
template<class... Args>
constexpr decltype(auto) operator()(Args&&... args) const
noexcept(is_nothrow_invocable_v<T&, Args...>)
{
return get(based::forward<Args>(args)...);
}
private:
T* m_ptr;
};
// deduction guides
template<class T>
reference_wrapper(T&) -> reference_wrapper<T>;
} // namespace based
diff --git a/ include/based/instrumentation/instrumented.hpp b/ include/based/instrumentation/instrumented.hpp
@@ -10,6 +10,7 @@
#include "based/enum/enum.hpp"
#include "based/instrumentation/table.hpp"
#include "based/types/types.hpp"
#include "based/utility/move.hpp"
namespace based
{
@@ -65,14 +66,14 @@
struct instrumented : instrumented_base
value_type value;
instrumented(const value_type& val) // NOLINT(*explicit*)
: value(std::move(val))
: value(based::move(val))
{
++counts[op::ctor_value];
;
}
instrumented(value_type&& val) // NOLINT(*explicit*)
: value(std::move(val))
: value(based::move(val))
{
++counts[op::ctor_value];
;
@@ -93,7 +94,7 @@
struct instrumented : instrumented_base
}
instrumented(instrumented&& val) noexcept
: value(std::move(val.value))
: value(based::move(val.value))
{
++counts[op::ctor_move];
;
@@ -114,7 +115,7 @@
struct instrumented : instrumented_base
{
++counts[op::asgn_move];
;
value = std::move(val.value);
value = based::move(val.value);
return *this;
}
diff --git a/ include/based/list.hpp b/ include/based/list.hpp
@@ -1,7 +1,6 @@
#pragma once
#include <cassert>
#include <utility>
#include <vector>
namespace based
@@ -213,9 +212,7 @@
public:
[[nodiscard]] bool is_empty(const queue_t& queue) const
{
return is_empty(queue.first);
}
[[nodiscard]] queue_t queue_empty() { return {node_empty(), node_empty()}; }
return is_empty(queue.first); } [[nodiscard]] queue_t queue_empty() { return {node_empty(), node_empty()}; }
[[nodiscard]] queue_t push_front(const queue_t& queue, const value_type& val)
{
diff --git a/ include/based/memory/addressof.hpp b/ include/based/memory/addressof.hpp
@@ -0,0 +1,25 @@
#pragma once
#include "based/trait/is/object.hpp"
namespace based
{
template<class T>
T* addressof(T& arg) noexcept
{
return &arg;
}
template<class T>
requires is_object_v<T>
T* addressof(T& arg) noexcept
{
// NOLINTBEGIN(*reinterpret*,*const*)
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char&>(arg))
);
// NOLINTEND(*reinterpret*,*const*)
}
} // namespace based
diff --git a/ include/based/trait/add/pointer.hpp b/ include/based/trait/add/pointer.hpp
@@ -0,0 +1,25 @@
#pragma once
#include "based/trait/remove/reference.hpp"
#include "based/trait/type_identity.hpp"
namespace based
{
// clang-format off
namespace detail
{
template<class T> type_identity<remove_reference_t<T>*> try_add_pointer(int);
template<class T> type_identity<T> try_add_pointer(...);
} // namespace detail
template<class T> struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
template<class T> using add_pointer_t = add_pointer<T>::type;
// clang-format on
} // namespace based
diff --git a/ include/based/trait/conditional.hpp b/ include/based/trait/conditional.hpp
@@ -0,0 +1,15 @@
#pragma once
namespace based
{
// clang-format off
template<bool b, class T, class F> struct conditional { using type = T; };
template<class T, class F> struct conditional<false, T, F> { using type = F; };
template<bool b, class T, class F> using conditional_t = conditional<b, T, F>::type;
// clang-format on
} // namespace based
diff --git a/ include/based/trait/decay.hpp b/ include/based/trait/decay.hpp
@@ -0,0 +1,37 @@
#pragma once
#include "based/trait/add/pointer.hpp"
#include "based/trait/conditional.hpp"
#include "based/trait/is/array.hpp"
#include "based/trait/is/function.hpp"
#include "based/trait/remove/cv.hpp"
#include "based/trait/remove/extent.hpp"
#include "based/trait/remove/reference.hpp"
namespace based
{
// clang-format off
template<class T>
struct decay
{
private:
using u = remove_reference_t<T>;
public:
using type = conditional_t<
is_array_v<u>,
add_pointer_t<remove_extent_t<u>>,
conditional_t<
is_function_v<u>,
add_pointer_t<u>,
remove_cv_t<u>>
>;
};
template<class T> using decay_t = typename decay<T>::type;
// clang-format on
} // namespace based
diff --git a/ include/based/trait/enable_if.hpp b/ include/based/trait/enable_if.hpp
@@ -0,0 +1,15 @@
#pragma once
namespace based
{
// clang-format off
template<bool b, class T = void> struct enable_if {};
template<class T> struct enable_if<true, T> { using type = T; };
template<bool b, class T = void> using enable_if_t = typename enable_if<b, T>::type;
// clang-format on
} // namespace based
diff --git a/ include/based/trait/integral_constant.hpp b/ include/based/trait/integral_constant.hpp
@@ -16,7 +16,10 @@
struct integral_constant
constexpr value_type operator()() const noexcept { return value; }
};
using true_type = integral_constant<bool, true>;
using false_type = integral_constant<bool, false>;
template<bool b>
using bool_constant = integral_constant<bool, b>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
} // namespace based
diff --git a/ include/based/trait/invoke/result.hpp b/ include/based/trait/invoke/result.hpp
@@ -1,77 +1,90 @@
#pragma once
#include <type_traits>
#include <utility>
#include "based/trait/decay.hpp"
#include "based/trait/is/base_of.hpp"
#include "based/trait/is/reference_wrapper.hpp"
#include "based/utility/forward.hpp"
namespace based
{
namespace detail
{
template<class T>
struct is_reference_wrapper : std::false_type
{
};
template<class U>
struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type
{
};
template<class T>
struct invoke_impl
{
template<class F, class... Args>
static auto call(F&& f, Args&&... args)
-> decltype(std::forward<F>(f)(std::forward<Args>(args)...));
static auto call(F&& func, Args&&... args)
-> decltype(based::forward<F>(func)(based::forward<Args>(args)...));
};
template<class B, class MT>
struct invoke_impl<MT B::*>
{
template<
class T,
class Td = typename std::decay<T>::type,
class = typename std::enable_if<std::is_base_of<B, Td>::value>::type>
static auto get(T&& t) -> T&&;
template<
class T,
class Td = typename std::decay<T>::type,
class = typename std::enable_if<is_reference_wrapper<Td>::value>::type>
static auto get(T&& t) -> decltype(t.get());
template<
class T,
class Td = typename std::decay<T>::type,
class = typename std::enable_if<!std::is_base_of<B, Td>::value>::type,
class = typename std::enable_if<!is_reference_wrapper<Td>::value>::type>
static auto get(T&& t) -> decltype(*std::forward<T>(t));
template<
class T,
class... Args,
class MT1,
class = typename std::enable_if<std::is_function<MT1>::value>::type>
static auto call(MT1 B::* pmf, T&& t, Args&&... args)
-> decltype((invoke_impl::get(std::forward<T>(t)).*pmf)(
std::forward<Args>(args)...
));
template<class T>
requires(is_base_of_v<B, decay_t<T>>)
static auto get(T&& obj) -> T&&;
template<class T>
requires(is_reference_wrapper_v<decay_t<T>>)
static auto get(T&& obj) -> decltype(obj.get());
template<class T>
static auto call(MT B::* pmd, T&& t)
-> decltype(invoke_impl::get(std::forward<T>(t)).*pmd);
requires(!is_base_of_v<B, decay_t<T>> && !is_reference_wrapper_v<decay<T>>)
static auto get(T&& obj) -> decltype(*based::forward<T>(obj));
template<class T, class... Args, class MT1>
requires(is_function_v<MT1>)
static auto call(MT1 B::* pmf, T&& obj, Args&&... args)
-> decltype((invoke_impl::get(based::forward<T>(obj)).*pmf)(based::forward<Args>(args
)...));
template<class T>
static auto call(MT B::* pmd, T&& obj)
-> decltype(invoke_impl::get(based::forward<T>(obj)).*pmd);
};
template<class F, class... Args, class Fd = typename std::decay<F>::type>
auto INVOKE(F&& f, Args&&... args) -> decltype(invoke_impl<Fd>::call(
std::forward<F>(f), std::forward<Args>(args)...
template<class F, class... Args>
auto INVOKE(F&& func, Args&&... args) -> decltype(invoke_impl<decay_t<F>>::call(
based::forward<F>(func), based::forward<Args>(args)...
));
} // namespace detail
namespace detail
{
template<typename AlwaysVoid, typename, typename...>
struct invoke_result
{
};
template<typename F, typename... Args>
struct invoke_result<
decltype(void(detail::INVOKE(declval<F>(), declval<Args>()...))),
F,
Args...>
{
using type = decltype(detail::INVOKE(declval<F>(), declval<Args>()...));
};
} // namespace detail
/*
template<class F, class... Args>
struct invoke_result : detail::invoke_result<void, F, Args...>
{
};
template<class F, class... Args>
using invoke_result_t = typename invoke_result<F, Args...>::type;
*/
template<class F, class... Args>
using invoke_result = std::invoke_result<F, Args...>;
template<class F, class... Args>
using invoke_result_t = invoke_result<F, Args...>::type;
using invoke_result_t = std::invoke_result_t<F, Args...>;
} // namespace based
diff --git a/ include/based/trait/is/arithmetic.hpp b/ include/based/trait/is/arithmetic.hpp
@@ -0,0 +1,18 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/floating_point.hpp"
#include "based/trait/is/integral.hpp"
namespace based
{
template<class T>
struct is_arithmetic : bool_constant<is_integral_v<T> || is_floating_point_v<T>>
{
};
template<class T>
constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/array.hpp b/ include/based/trait/is/array.hpp
@@ -0,0 +1,29 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/types/types.hpp"
namespace based
{
// NOLINTBEGIN(*array*)
template<class T>
struct is_array : false_type
{
};
template<class T>
struct is_array<T[]> : true_type
{
};
template<class T, size_t n>
struct is_array<T[n]> : true_type
{
};
// NOLINTEND(*array*)
template<class T>
constexpr bool is_array_v = is_array<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/base_of.hpp b/ include/based/trait/is/base_of.hpp
@@ -0,0 +1,44 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/class.hpp"
namespace based
{
namespace details
{
template<class B>
true_type test_ptr_conv(const volatile B*);
template<class>
false_type test_ptr_conv(const volatile void*);
template<class B, class D>
auto test_is_base_of(int)
-> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));
template<class, class>
auto test_is_base_of(...) -> true_type; // private or ambiguous base
} // namespace details
template<class Base, class Derived>
struct is_base_of : false_type
{
};
template<class Base, class Derived>
requires(
is_class_v<Base> && is_class_v<Derived>
&& decltype(details::test_is_base_of<Base, Derived>(0))::value
)
struct is_base_of<Base, Derived> : true_type
{
};
template<class Base, class Derived>
constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
} // namespace based
diff --git a/ include/based/trait/is/class.hpp b/ include/based/trait/is/class.hpp
@@ -0,0 +1,28 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/union.hpp"
namespace based
{
namespace detail
{
template<class T>
bool_constant<!is_union_v<T>> test(int T::*);
template<class T>
false_type test(...);
} // namespace detail
template<class T>
struct is_class : decltype(detail::test<T>(nullptr))
{
};
template<class T>
constexpr bool is_class_v = is_class<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/const.hpp b/ include/based/trait/is/const.hpp
@@ -5,13 +5,17 @@
namespace based
{
// clang-format off
template<class T> struct is_const : false_type {};
template<class T> struct is_const<const T> : true_type {};
template<class T>
struct is_const : false_type
{
};
template<class T> constexpr bool is_const_v = is_const<T>::value;
template<class T>
struct is_const<const T> : true_type
{
};
// clang-format on
template<class T>
constexpr bool is_const_v = is_const<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/enum.hpp b/ include/based/trait/is/enum.hpp
@@ -0,0 +1,14 @@
#pragma once
#include <type_traits>
namespace based
{
template<class T>
using is_enum = std::is_enum<T>;
template<class T>
constexpr bool is_enum_v = std::is_enum_v<T>;
} // namespace based
diff --git a/ include/based/trait/is/floating_point.hpp b/ include/based/trait/is/floating_point.hpp
@@ -0,0 +1,24 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/same.hpp"
#include "based/trait/remove/cv.hpp"
namespace based
{
template<class T>
struct is_floating_point : false_type
{
};
template<class T>
requires(is_same_v<float, remove_cv_t<T>> || is_same_v<double, remove_cv_t<T>> || is_same_v<long double, remove_cv_t<T>>)
struct is_floating_point<T> : true_type
{
};
template<class T>
constexpr bool is_floating_point_v = is_floating_point<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/function.hpp b/ include/based/trait/is/function.hpp
@@ -0,0 +1,93 @@
#pragma once
#include "based/trait/integral_constant.hpp"
namespace based
{
// clang-format off
template<typename>
struct is_function : false_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) volatile noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) volatile & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) volatile && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const volatile noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const volatile & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args...) const volatile && noexcept(ne)> : true_type {};
// NOLINTBEGIN(*ambiguous-ellipsis*)
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) volatile noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) volatile & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) volatile && noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const volatile noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const volatile & noexcept(ne)> : true_type {};
template<typename Ret, bool ne, typename... Args>
struct is_function<Ret(Args......) const volatile && noexcept(ne)> : true_type {};
// NOLINTEND(*ambiguous-ellipsis*)
template<class T> constexpr bool is_function_v = is_function<T>::value;
// clang-format on
} // namespace based
diff --git a/ include/based/trait/is/integral.hpp b/ include/based/trait/is/integral.hpp
@@ -0,0 +1,31 @@
#pragma once
#include "based/trait/integral_constant.hpp"
namespace based
{
template<class T>
struct is_integral : false_type
{
};
template<class T>
requires(
requires(
T obj, T* ptr, void (*func)(T)
) // T* parameter excludes reference types
{
reinterpret_cast<T>(obj); // NOLINT(*reinterpret*, *redundant*)
func(0); // Exclude enumeration types
ptr + obj; // Exclude everything not yet excluded but integral types
}
)
struct is_integral<T> : true_type
{
};
template<class T>
constexpr bool is_integral_v = is_integral<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/invocable.hpp b/ include/based/trait/is/invocable.hpp
@@ -9,6 +9,12 @@
template<class F, class... Args>
using is_invocable = std::is_invocable<F, Args...>;
template<class F, class... Args>
constexpr bool is_invocable_v = is_invocable<F, Args...>::value;
constexpr bool is_invocable_v = std::is_invocable_v<F, Args...>;
template<class F, class... Args>
using is_nothrow_invocable = std::is_nothrow_invocable<F, Args...>;
template<class F, class... Args>
constexpr bool is_nothrow_invocable_v = std::is_nothrow_invocable_v<F, Args...>;
} // namespace based
diff --git a/ include/based/trait/is/lvalue_reference.hpp b/ include/based/trait/is/lvalue_reference.hpp
@@ -5,13 +5,17 @@
namespace based
{
// clang-format off
template <class T> struct is_lvalue_reference : false_type {};
template <class T> struct is_lvalue_reference<T&> : true_type {};
template<class T>
struct is_lvalue_reference : false_type
{
};
template <class T> constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
template<class T>
struct is_lvalue_reference<T&> : true_type
{
};
// clang-format on
template<class T>
constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/member_pointer.hpp b/ include/based/trait/is/member_pointer.hpp
@@ -0,0 +1,32 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/remove/cv.hpp"
namespace based
{
namespace detail
{
template<class T>
struct is_member_pointer_helper : false_type
{
};
template<class T, class U>
struct is_member_pointer_helper<T U::*> : true_type
{
};
} // namespace detail
template<class T>
struct is_member_pointer : detail::is_member_pointer_helper<remove_cv_t<T>>
{
};
template<class T>
constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/null_pointer.hpp b/ include/based/trait/is/null_pointer.hpp
@@ -0,0 +1,18 @@
#pragma once
#include "based/trait/is/same.hpp"
#include "based/trait/remove/cv.hpp"
#include "based/types/nullptr.hpp"
namespace based
{
template<class T>
struct is_null_pointer : is_same<nullptr_t, remove_cv_t<T>>
{
};
template<class T>
constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/object.hpp b/ include/based/trait/is/object.hpp
@@ -0,0 +1,26 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/array.hpp"
#include "based/trait/is/class.hpp"
#include "based/trait/is/scalar.hpp"
#include "based/trait/is/union.hpp"
namespace based
{
template<class T>
struct is_object : false_type
{
};
template<class T>
requires(is_scalar_v<T> || is_array_v<T> || is_union_v<T> || is_class_v<T>)
struct is_object<T> : true_type
{
};
template<class T>
constexpr bool is_object_v = is_object<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/pointer.hpp b/ include/based/trait/is/pointer.hpp
@@ -0,0 +1,36 @@
#pragma once
#include "based/trait/integral_constant.hpp"
namespace based
{
template<class T>
struct is_pointer : false_type
{
};
template<class T>
struct is_pointer<T*> : true_type
{
};
template<class T>
struct is_pointer<T* const> : true_type
{
};
template<class T>
struct is_pointer<T* volatile> : true_type
{
};
template<class T>
struct is_pointer<T* const volatile> : true_type
{
};
template<class T>
constexpr bool is_pointer_v = is_pointer<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/reference_wrapper.hpp b/ include/based/trait/is/reference_wrapper.hpp
@@ -0,0 +1,21 @@
#pragma once
#include "based/functional/reference_wrapper.hpp"
namespace based
{
template<class T>
struct is_reference_wrapper : false_type
{
};
template<class U>
struct is_reference_wrapper<reference_wrapper<U>> : true_type
{
};
template<class T>
constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/rvalue_reference.hpp b/ include/based/trait/is/rvalue_reference.hpp
@@ -5,13 +5,17 @@
namespace based
{
// clang-format off
template <class T> struct is_rvalue_reference : false_type {};
template <class T> struct is_rvalue_reference<T&&> : true_type {};
template<class T>
struct is_rvalue_reference : false_type
{
};
template <class T> constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
template<class T>
struct is_rvalue_reference<T&&> : true_type
{
};
// clang-format on
template<class T>
constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/same.hpp b/ include/based/trait/is/same.hpp
@@ -5,13 +5,17 @@
namespace based
{
// clang-format off
template<class T, class U> struct is_same : false_type {};
template<class T> struct is_same<T, T> : true_type {};
template<class T, class U>
struct is_same : false_type
{
};
template<class T, class U> constexpr bool is_same_v = is_same<T, U>::value;
template<class T>
struct is_same<T, T> : true_type
{
};
// clang-format on
template<class T, class U>
constexpr bool is_same_v = is_same<T, U>::value;
} // namespace based
diff --git a/ include/based/trait/is/scalar.hpp b/ include/based/trait/is/scalar.hpp
@@ -0,0 +1,27 @@
#pragma once
#include "based/trait/integral_constant.hpp"
#include "based/trait/is/arithmetic.hpp"
#include "based/trait/is/enum.hpp"
#include "based/trait/is/member_pointer.hpp"
#include "based/trait/is/null_pointer.hpp"
#include "based/trait/is/pointer.hpp"
namespace based
{
template<class T>
struct is_scalar : false_type
{
};
template<class T>
requires(is_arithmetic_v<T> || is_enum_v<T> || is_pointer_v<T> || is_member_pointer_v<T> || is_null_pointer_v<T>)
struct is_scalar<T>
{
};
template<class T>
constexpr bool is_scalar_v = is_scalar<T>::value;
} // namespace based
diff --git a/ include/based/trait/is/union.hpp b/ include/based/trait/is/union.hpp
@@ -0,0 +1,14 @@
#pragma once
#include <type_traits>
namespace based
{
template<class T>
using is_union = std::is_union<T>;
template<class T>
constexpr bool is_union_v = std::is_union_v<T>;
} // namespace based
diff --git a/ include/based/trait/is/void.hpp b/ include/based/trait/is/void.hpp
@@ -0,0 +1,17 @@
#pragma once
#include "based/trait/is/same.hpp"
#include "based/trait/remove/cv.hpp"
namespace based
{
template<class T>
struct is_void : is_same<void, remove_cv_t<T>>
{
};
template<class T>
constexpr bool is_void_v = is_void<T>::value;
} // namespace based
diff --git a/ include/based/trait/remove/extent.hpp b/ include/based/trait/remove/extent.hpp
@@ -0,0 +1,26 @@
#pragma once
#include "based/types/types.hpp"
namespace based
{
// NOLINTBEGIN(*array*)
// clang-format off
template<class T>
struct remove_extent { using type = T; };
template<class T>
struct remove_extent<T[]> { using type = T; };
template<class T, size_t n>
struct remove_extent<T[n]> { using type = T; };
template<class T> using remove_extent_t = remove_extent<T>::type;
// NOLINTEND(*array*)
// clang-format on
} // namespace based
diff --git a/ include/based/types/nullptr.hpp b/ include/based/types/nullptr.hpp
@@ -0,0 +1,8 @@
#pragma once
namespace based
{
using nullptr_t = decltype(nullptr);
} // namespace based
diff --git a/ include/based/utility/buffer.hpp b/ include/based/utility/buffer.hpp
@@ -5,6 +5,7 @@
#include <utility>
#include "based/types/types.hpp"
#include "based/utility/forward.hpp"
namespace based
{
@@ -32,7 +33,7 @@
struct buffer
{
static_assert(std::is_trivially_destructible_v<T>);
static_assert(std::is_trivially_copyable_v<T>);
::new (static_cast<void*>(as<T>())) T(std::forward<Args>(args)...);
::new (static_cast<void*>(as<T>())) T(based::forward<Args>(args)...);
}
template<typename T, typename... Args>
@@ -44,7 +45,7 @@
struct buffer
static_assert(std::is_trivially_copyable_v<T>);
// NOLINTNEXTLINE(*owning-memory*)
return ::new (static_cast<void*>(as<T>())) T(std::forward<Args>(args)...);
return ::new (static_cast<void*>(as<T>())) T(based::forward<Args>(args)...);
}
template<typename T>
diff --git a/ include/based/utility/forward.hpp b/ include/based/utility/forward.hpp
@@ -7,14 +7,14 @@
namespace based
{
template<class T>
constexpr auto forward(remove_reference_t<T>& tmp) noexcept
constexpr decltype(auto) forward(remove_reference_t<T>& tmp) noexcept
{
return static_cast<T&&>(tmp);
}
template<class T>
// NOLINTNEXTLINE(*move*)
constexpr auto forward(remove_reference_t<T>&& tmp) noexcept
constexpr decltype(auto) forward(remove_reference_t<T>&& tmp) noexcept
{
static_assert(!is_lvalue_reference_v<T>);
return static_cast<T&&>(tmp);
diff --git a/ include/based/utility/move.hpp b/ include/based/utility/move.hpp
@@ -7,7 +7,7 @@
namespace based
template<class T>
// NOLINTNEXTLINE(*forward*)
constexpr auto move(T&& tmp) noexcept
constexpr decltype(auto) move(T&& tmp) noexcept
{
return static_cast<remove_reference_t<T>&&>(tmp);
}
diff --git a/ include/based/utility/scopeguard.hpp b/ include/based/utility/scopeguard.hpp
@@ -1,5 +1,6 @@
#pragma once
#include "based/utility/move.hpp"
#include "based/utility/uncaught_exception.hpp"
namespace based
@@ -13,7 +14,7 @@
class scopeguard
public:
scopeguard(Func&& func) // NOLINT(*explicit*)
: m_func(std::move(func))
: m_func(based::move(func))
{
}
@@ -46,7 +47,7 @@
class scopeguard<Func, false, false>
public:
scopeguard(Func&& func) // NOLINT(*explicit*)
: m_func(std::move(func))
: m_func(based::move(func))
{
}
diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt
@@ -28,13 +28,24 @@
endfunction()
## ----- Type Traits -----
add_test(trait remove_const)
add_test(trait remove_cv)
add_test(trait remove_cvref)
add_test(trait remove_pointer)
add_test(trait remove_reference)
add_test(trait remove_volatile)
add_test(trait signature_test)
add_test(trait invoke_result_test)
add_test(trait is_array_test)
add_test(trait is_base_of_test)
add_test(trait is_class_test)
add_test(trait is_const_test)
add_test(trait is_enum_test)
add_test(trait is_lvalue_reference_test)
add_test(trait is_null_pointer_test)
add_test(trait is_rvalue_reference_test)
add_test(trait is_void_test)
add_test(trait remove_const_test)
add_test(trait remove_cvref_test)
add_test(trait remove_cv_test)
add_test(trait remove_pointer_test)
add_test(trait remove_reference_test)
add_test(trait remove_volatile_test)
add_test(trait signature_test_test)
## ----- Concepts -----
diff --git a/ test/source/algorithms/max_test.cpp b/ test/source/algorithms/max_test.cpp
@@ -5,6 +5,7 @@
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/utility/move.hpp"
// NOLINTBEGIN(*const-arg*,*const-correctness*,*after-move, *access-moved)
@@ -196,20 +197,20 @@
TEST_CASE("max(move, literal) = right", "[algorithm/max]")
{
int a = 3;
using res_t = decltype(based::max(std::move(a), 4));
using res_t = decltype(based::max(based::move(a), 4));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(std::move(a), 4) == 4);
REQUIRE(based::max(based::move(a), 4) == 4);
}
TEST_CASE("max(move, literal) = left", "[algorithm/max]")
{
int a = 4;
using res_t = decltype(based::max(std::move(a), 3));
using res_t = decltype(based::max(based::move(a), 3));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(std::move(a), 3) == 4);
REQUIRE(based::max(based::move(a), 3) == 4);
}
TEST_CASE("max(move, value) = right", "[algorithm/max]")
@@ -217,10 +218,10 @@
TEST_CASE("max(move, value) = right", "[algorithm/max]")
int a = 3;
int b = 4;
using res_t = decltype(based::max(std::move(a), b));
using res_t = decltype(based::max(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(std::move(a), b) == 4);
REQUIRE(based::max(based::move(a), b) == 4);
}
TEST_CASE("max(move, value) = left", "[algorithm/max]")
@@ -228,10 +229,10 @@
TEST_CASE("max(move, value) = left", "[algorithm/max]")
int a = 4;
int b = 3;
using res_t = decltype(based::max(std::move(a), b));
using res_t = decltype(based::max(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(std::move(a), b) == 4);
REQUIRE(based::max(based::move(a), b) == 4);
}
TEST_CASE("max(move, const value) = right", "[algorithm/max]")
@@ -239,10 +240,10 @@
TEST_CASE("max(move, const value) = right", "[algorithm/max]")
int a = 3;
const int b = 4;
using res_t = decltype(based::max(std::move(a), b));
using res_t = decltype(based::max(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(std::move(a), b) == 4);
REQUIRE(based::max(based::move(a), b) == 4);
}
TEST_CASE("max(move, const value) = left", "[algorithm/max]")
@@ -250,30 +251,30 @@
TEST_CASE("max(move, const value) = left", "[algorithm/max]")
int a = 4;
const int b = 3;
using res_t = decltype(based::max(std::move(a), b));
using res_t = decltype(based::max(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(std::move(a), b) == 4);
REQUIRE(based::max(based::move(a), b) == 4);
}
TEST_CASE("max(literal, move) = right", "[algorithm/max]")
{
int b = 4;
using res_t = decltype(based::max(3, std::move(b)));
using res_t = decltype(based::max(3, based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(3, std::move(b)) == 4);
REQUIRE(based::max(3, based::move(b)) == 4);
}
TEST_CASE("max(literal, move) = left", "[algorithm/max]")
{
int b = 3;
using res_t = decltype(based::max(4, std::move(b)));
using res_t = decltype(based::max(4, based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(4, std::move(b)) == 4);
REQUIRE(based::max(4, based::move(b)) == 4);
}
TEST_CASE("max(value, move) = right", "[algorithm/max]")
@@ -281,10 +282,10 @@
TEST_CASE("max(value, move) = right", "[algorithm/max]")
int a = 3;
int b = 4;
using res_t = decltype(based::max(a, std::move(b)));
using res_t = decltype(based::max(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(a, std::move(b)) == 4);
REQUIRE(based::max(a, based::move(b)) == 4);
}
TEST_CASE("max(value, move) = left", "[algorithm/max]")
@@ -292,10 +293,10 @@
TEST_CASE("max(value, move) = left", "[algorithm/max]")
int a = 4;
int b = 3;
using res_t = decltype(based::max(a, std::move(b)));
using res_t = decltype(based::max(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(a, std::move(b)) == 4);
REQUIRE(based::max(a, based::move(b)) == 4);
}
TEST_CASE("max(const value, move) = right", "[algorithm/max]")
@@ -303,10 +304,10 @@
TEST_CASE("max(const value, move) = right", "[algorithm/max]")
const int a = 3;
int b = 4;
using res_t = decltype(based::max(a, std::move(b)));
using res_t = decltype(based::max(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(a, std::move(b)) == 4);
REQUIRE(based::max(a, based::move(b)) == 4);
}
TEST_CASE("max(const value, move) = left", "[algorithm/max]")
@@ -314,10 +315,10 @@
TEST_CASE("max(const value, move) = left", "[algorithm/max]")
const int a = 4;
int b = 3;
using res_t = decltype(based::max(a, std::move(b)));
using res_t = decltype(based::max(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::max(a, std::move(b)) == 4);
REQUIRE(based::max(a, based::move(b)) == 4);
}
TEST_CASE("max(move, move) = right", "[algorithm/max]")
@@ -325,10 +326,10 @@
TEST_CASE("max(move, move) = right", "[algorithm/max]")
int a = 3;
int b = 4;
using res_t = decltype(based::max(std::move(a), std::move(b)));
using res_t = decltype(based::max(based::move(a), based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(std::move(a), std::move(b)) == 4);
REQUIRE(based::max(based::move(a), based::move(b)) == 4);
}
TEST_CASE("max(move, move) = left", "[algorithm/max]")
@@ -336,10 +337,10 @@
TEST_CASE("max(move, move) = left", "[algorithm/max]")
int a = 4;
int b = 3;
using res_t = decltype(based::max(std::move(a), std::move(b)));
using res_t = decltype(based::max(based::move(a), based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::max(std::move(a), std::move(b)) == 4);
REQUIRE(based::max(based::move(a), based::move(b)) == 4);
}
// NOLINTEND(*const-arg*,*const-correctness*,*after-move, *access-moved)
diff --git a/ test/source/algorithms/min_test.cpp b/ test/source/algorithms/min_test.cpp
@@ -4,6 +4,8 @@
#include <catch2/catch_test_macros.hpp>
#include "based/utility/move.hpp"
// NOLINTBEGIN(*const-arg*,*const-correctness*,*after-move, *access-moved)
TEST_CASE("min(literal, literal) = left", "[algorithm/min]")
@@ -194,20 +196,20 @@
TEST_CASE("min(move, literal) = left", "[algorithm/min]")
{
int a = 3;
using res_t = decltype(based::min(std::move(a), 4));
using res_t = decltype(based::min(based::move(a), 4));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(std::move(a), 4) == 3);
REQUIRE(based::min(based::move(a), 4) == 3);
}
TEST_CASE("min(move, literal) = right", "[algorithm/min]")
{
int a = 4;
using res_t = decltype(based::min(std::move(a), 3));
using res_t = decltype(based::min(based::move(a), 3));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(std::move(a), 3) == 3);
REQUIRE(based::min(based::move(a), 3) == 3);
}
TEST_CASE("min(move, value) = left", "[algorithm/min]")
@@ -215,10 +217,10 @@
TEST_CASE("min(move, value) = left", "[algorithm/min]")
int a = 3;
int b = 4;
using res_t = decltype(based::min(std::move(a), b));
using res_t = decltype(based::min(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(std::move(a), b) == 3);
REQUIRE(based::min(based::move(a), b) == 3);
}
TEST_CASE("min(move, value) = right", "[algorithm/min]")
@@ -226,10 +228,10 @@
TEST_CASE("min(move, value) = right", "[algorithm/min]")
int a = 4;
int b = 3;
using res_t = decltype(based::min(std::move(a), b));
using res_t = decltype(based::min(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(std::move(a), b) == 3);
REQUIRE(based::min(based::move(a), b) == 3);
}
TEST_CASE("min(move, const value) = left", "[algorithm/min]")
@@ -237,10 +239,10 @@
TEST_CASE("min(move, const value) = left", "[algorithm/min]")
int a = 3;
const int b = 4;
using res_t = decltype(based::min(std::move(a), b));
using res_t = decltype(based::min(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(std::move(a), b) == 3);
REQUIRE(based::min(based::move(a), b) == 3);
}
TEST_CASE("min(move, const value) = right", "[algorithm/min]")
@@ -248,30 +250,30 @@
TEST_CASE("min(move, const value) = right", "[algorithm/min]")
int a = 4;
const int b = 3;
using res_t = decltype(based::min(std::move(a), b));
using res_t = decltype(based::min(based::move(a), b));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(std::move(a), b) == 3);
REQUIRE(based::min(based::move(a), b) == 3);
}
TEST_CASE("min(literal, move) = left", "[algorithm/min]")
{
int b = 4;
using res_t = decltype(based::min(3, std::move(b)));
using res_t = decltype(based::min(3, based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(3, std::move(b)) == 3);
REQUIRE(based::min(3, based::move(b)) == 3);
}
TEST_CASE("min(literal, move) = right", "[algorithm/min]")
{
int b = 3;
using res_t = decltype(based::min(4, std::move(b)));
using res_t = decltype(based::min(4, based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(4, std::move(b)) == 3);
REQUIRE(based::min(4, based::move(b)) == 3);
}
TEST_CASE("min(value, move) = left", "[algorithm/min]")
@@ -279,10 +281,10 @@
TEST_CASE("min(value, move) = left", "[algorithm/min]")
int a = 3;
int b = 4;
using res_t = decltype(based::min(a, std::move(b)));
using res_t = decltype(based::min(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(a, std::move(b)) == 3);
REQUIRE(based::min(a, based::move(b)) == 3);
}
TEST_CASE("min(value, move) = right", "[algorithm/min]")
@@ -290,10 +292,10 @@
TEST_CASE("min(value, move) = right", "[algorithm/min]")
int a = 4;
int b = 3;
using res_t = decltype(based::min(a, std::move(b)));
using res_t = decltype(based::min(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(a, std::move(b)) == 3);
REQUIRE(based::min(a, based::move(b)) == 3);
}
TEST_CASE("min(const value, move) = left", "[algorithm/min]")
@@ -301,10 +303,10 @@
TEST_CASE("min(const value, move) = left", "[algorithm/min]")
const int a = 3;
int b = 4;
using res_t = decltype(based::min(a, std::move(b)));
using res_t = decltype(based::min(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(a, std::move(b)) == 3);
REQUIRE(based::min(a, based::move(b)) == 3);
}
TEST_CASE("min(const value, move) = right", "[algorithm/min]")
@@ -312,10 +314,10 @@
TEST_CASE("min(const value, move) = right", "[algorithm/min]")
const int a = 4;
int b = 3;
using res_t = decltype(based::min(a, std::move(b)));
using res_t = decltype(based::min(a, based::move(b)));
STATIC_REQUIRE(based::SameAs<int, res_t>);
REQUIRE(based::min(a, std::move(b)) == 3);
REQUIRE(based::min(a, based::move(b)) == 3);
}
TEST_CASE("min(move, move) = left", "[algorithm/min]")
@@ -323,10 +325,10 @@
TEST_CASE("min(move, move) = left", "[algorithm/min]")
int a = 3;
int b = 4;
using res_t = decltype(based::min(std::move(a), std::move(b)));
using res_t = decltype(based::min(based::move(a), based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(std::move(a), std::move(b)) == 3);
REQUIRE(based::min(based::move(a), based::move(b)) == 3);
}
TEST_CASE("min(move, move) = right", "[algorithm/min]")
@@ -334,10 +336,10 @@
TEST_CASE("min(move, move) = right", "[algorithm/min]")
int a = 4;
int b = 3;
using res_t = decltype(based::min(std::move(a), std::move(b)));
using res_t = decltype(based::min(based::move(a), based::move(b)));
STATIC_REQUIRE(based::SameAs<int&&, res_t>);
REQUIRE(based::min(std::move(a), std::move(b)) == 3);
REQUIRE(based::min(based::move(a), based::move(b)) == 3);
}
// NOLINTEND(*const-arg*,*const-correctness*,*after-move, *access-moved)
diff --git a/ test/source/concepts/callable_test.cpp b/ test/source/concepts/callable_test.cpp
@@ -50,7 +50,7 @@
struct func
TEST_CASE("member function", "[trait/callable]")
{
// [&](auto&&... args) -> decltype(auto) { return
// f(std::forward<decltype(args)>(args)...); }
// f(based::forward<decltype(args)>(args)...); }
// based::error_template<decltype(&func::template operator()<int, double>)>();
STATIC_REQUIRE(based::Callable<func>);
diff --git a/ test/source/trait/invoke_result_test.cpp b/ test/source/trait/invoke_result_test.cpp
@@ -0,0 +1,24 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/invoke/result.hpp"
int func(double);
template<class Res, class T, class... Args>
concept test = based::SameAs<based::invoke_result_t<T(Args...)>, Res>;
TEST_CASE("invoke_result", "[trait/invoke_result]")
{
// NOLINTBEGIN(*array*)
// clang-format off
/*
STATIC_REQUIRE(test<int, decltype(func), double>);
STATIC_REQUIRE(test<int, decltype(func), int>);
STATIC_REQUIRE(!test<int, decltype(func), char>);
*/
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_array_test.cpp b/ test/source/trait/is_array_test.cpp
@@ -0,0 +1,23 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/array.hpp"
TEST_CASE("is_array", "[trait/is_array]")
{
// clang-format off
struct test {};
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(!based::is_array_v<test>);
STATIC_REQUIRE(based::is_array_v<test[]>);
STATIC_REQUIRE(based::is_array_v<test[3]>);
STATIC_REQUIRE(!based::is_array_v<float>);
STATIC_REQUIRE(!based::is_array_v<int>);
STATIC_REQUIRE(based::is_array_v<int[]>);
STATIC_REQUIRE(based::is_array_v<int[3]>);
STATIC_REQUIRE(!based::is_array_v<std::array<int, 3>>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_base_of_test.cpp b/ test/source/trait/is_base_of_test.cpp
@@ -0,0 +1,25 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/base_of.hpp"
TEST_CASE("is_base_of", "[trait/is_base_of]")
{
// clang-format off
class a {};
class b : a {};
class c : b {};
class d {};
union e {};
using i = int;
STATIC_REQUIRE(based::is_base_of_v<a, a>);
STATIC_REQUIRE(based::is_base_of_v<a, b>);
STATIC_REQUIRE(based::is_base_of_v<a, c>);
STATIC_REQUIRE(!based::is_base_of_v<a, d>);
STATIC_REQUIRE(!based::is_base_of_v<b, a>);
STATIC_REQUIRE(!based::is_base_of_v<e, e>);
STATIC_REQUIRE(!based::is_base_of_v<i, i>);
// clang-format on
}
diff --git a/ test/source/trait/is_class_test.cpp b/ test/source/trait/is_class_test.cpp
@@ -0,0 +1,25 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/class.hpp"
TEST_CASE("is_class", "[trait/is_class]")
{
// clang-format off
struct a {};
class b {};
enum class e {};
union u { class uc {}; };
STATIC_REQUIRE(based::is_class<a>::value);
STATIC_REQUIRE(based::is_class_v<b>);
STATIC_REQUIRE(!based::is_class_v<b*>);
STATIC_REQUIRE(!based::is_class_v<b&>);
STATIC_REQUIRE(based::is_class_v<const b>);
STATIC_REQUIRE(!based::is_class<e>::value);
STATIC_REQUIRE(!based::is_class_v<u>);
STATIC_REQUIRE(based::is_class_v<u::uc>);
STATIC_REQUIRE(!based::is_class_v<int>);
// clang-format on
}
diff --git a/ test/source/trait/is_const_test.cpp b/ test/source/trait/is_const_test.cpp
@@ -0,0 +1,36 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/const.hpp"
TEST_CASE("is_const", "[trait/is_const]")
{
// clang-format off
struct test {};
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(!based::is_const_v<int>);
STATIC_REQUIRE(!based::is_const_v<int&>);
STATIC_REQUIRE(!based::is_const_v<int&&>);
STATIC_REQUIRE(!based::is_const_v<int[2]>);
STATIC_REQUIRE(!based::is_const_v<int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<int(&&)[2]>);
STATIC_REQUIRE(based::is_const_v<const int>);
STATIC_REQUIRE(!based::is_const_v<const int&>);
STATIC_REQUIRE(based::is_const_v<const int[2]>);
STATIC_REQUIRE(!based::is_const_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<int(int)>);
STATIC_REQUIRE(!based::is_const_v<volatile int>);
STATIC_REQUIRE(!based::is_const_v<volatile int&>);
STATIC_REQUIRE(!based::is_const_v<volatile int&&>);
STATIC_REQUIRE(!based::is_const_v<volatile int[2]>);
STATIC_REQUIRE(!based::is_const_v<volatile int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<volatile int(&&)[2]>);
STATIC_REQUIRE(based::is_const_v<const volatile int>);
STATIC_REQUIRE(!based::is_const_v<const volatile int&>);
STATIC_REQUIRE(based::is_const_v<const volatile int[2]>);
STATIC_REQUIRE(!based::is_const_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_enum_test.cpp b/ test/source/trait/is_enum_test.cpp
@@ -0,0 +1,20 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/enum.hpp"
TEST_CASE("is_enum", "[trait/is_enum]")
{
// clang-format off
struct a { enum e {}; };
enum e {};
enum class ec : int {};
STATIC_REQUIRE(!based::is_enum_v<a>);
STATIC_REQUIRE(based::is_enum_v<a::e>);
STATIC_REQUIRE(based::is_enum_v<e>);
STATIC_REQUIRE(based::is_enum_v<ec>);
STATIC_REQUIRE(!based::is_enum_v<int>);
// clang-format !on
}
diff --git a/ test/source/trait/is_lvalue_reference.cpp b/ test/source/trait/is_lvalue_reference.cpp
@@ -1,34 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/lvalue_reference.hpp"
TEST_CASE("is_lvalue_reference", "[trait/is_lvalue_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_lvalue_reference_v<int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_lvalue_reference_test.cpp b/ test/source/trait/is_lvalue_reference_test.cpp
@@ -0,0 +1,34 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/lvalue_reference.hpp"
TEST_CASE("is_lvalue_reference", "[trait/is_lvalue_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_lvalue_reference_v<int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_null_pointer_test.cpp b/ test/source/trait/is_null_pointer_test.cpp
@@ -0,0 +1,23 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/null_pointer.hpp"
TEST_CASE("is_null_pointer", "[trait/is_null_pointer]")
{
double test = 0;
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(based::is_null_pointer_v<decltype(nullptr)>);
STATIC_REQUIRE(!based::is_null_pointer_v<void>);
STATIC_REQUIRE(!based::is_null_pointer_v<const void>);
STATIC_REQUIRE(!based::is_null_pointer_v<volatile void>);
STATIC_REQUIRE(!based::is_null_pointer_v<void*>);
STATIC_REQUIRE(!based::is_null_pointer_v<int>);
STATIC_REQUIRE(!based::is_null_pointer_v<decltype(test)>);
STATIC_REQUIRE(!based::is_null_pointer_v<std::is_null_pointer<void>>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_rvalue_reference.cpp b/ test/source/trait/is_rvalue_reference.cpp
@@ -1,34 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/rvalue_reference.hpp"
TEST_CASE("is_rvalue_reference", "[trait/is_rvalue_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_rvalue_reference_v<int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_rvalue_reference_test.cpp b/ test/source/trait/is_rvalue_reference_test.cpp
@@ -0,0 +1,34 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/rvalue_reference.hpp"
TEST_CASE("is_rvalue_reference", "[trait/is_rvalue_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_rvalue_reference_v<int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/is_void_test.cpp b/ test/source/trait/is_void_test.cpp
@@ -0,0 +1,22 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/trait/is/void.hpp"
TEST_CASE("is_void", "[trait/is_void]")
{
double test = 0;
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(based::is_void_v<void>);
STATIC_REQUIRE(based::is_void_v<const void>);
STATIC_REQUIRE(based::is_void_v<volatile void>);
STATIC_REQUIRE(!based::is_void_v<void*>);
STATIC_REQUIRE(!based::is_void_v<int>);
STATIC_REQUIRE(!based::is_void_v<decltype(test)>);
STATIC_REQUIRE(!based::is_void_v<std::is_void<void>>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_const.cpp b/ test/source/trait/remove_const.cpp
@@ -1,37 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/const.hpp"
using based::SameAs;
TEST_CASE("remove_const", "[trait/remove/remove_const]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_const_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_const_test.cpp b/ test/source/trait/remove_const_test.cpp
@@ -0,0 +1,37 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/const.hpp"
using based::SameAs;
TEST_CASE("remove_const", "[trait/remove/remove_const]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_const_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_const_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_cv.cpp b/ test/source/trait/remove_cv.cpp
@@ -1,37 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/cv.hpp"
using based::SameAs;
TEST_CASE("remove_cv", "[trait/remove_cv]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_cv_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_cv_test.cpp b/ test/source/trait/remove_cv_test.cpp
@@ -0,0 +1,37 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/cv.hpp"
using based::SameAs;
TEST_CASE("remove_cv", "[trait/remove_cv]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_cv_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cv_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_cvref.cpp b/ test/source/trait/remove_cvref.cpp
@@ -1,37 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/cvref.hpp"
using based::SameAs;
TEST_CASE("remove_cvref", "[trait/remove_cvref]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int(&)[2]>, int[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_cvref_test.cpp b/ test/source/trait/remove_cvref_test.cpp
@@ -0,0 +1,37 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/cvref.hpp"
using based::SameAs;
TEST_CASE("remove_cvref", "[trait/remove_cvref]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<volatile int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_cvref_t<const volatile int(&)[2]>, int[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_pointer.cpp b/ test/source/trait/remove_pointer.cpp
@@ -1,22 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/pointer.hpp"
using based::SameAs;
TEST_CASE("remove_pointer", "[trait/remove_pointer]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int*>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int**>, int*>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* const>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* volatile>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* const volatile>, int>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_pointer_test.cpp b/ test/source/trait/remove_pointer_test.cpp
@@ -0,0 +1,22 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/pointer.hpp"
using based::SameAs;
TEST_CASE("remove_pointer", "[trait/remove_pointer]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int*>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int**>, int*>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* const>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* volatile>, int>);
STATIC_REQUIRE(SameAs<based::remove_pointer_t<int* const volatile>, int>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_reference.cpp b/ test/source/trait/remove_reference.cpp
@@ -1,37 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/reference.hpp"
using based::SameAs;
TEST_CASE("remove_reference", "[trait/remove_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_reference_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int&>, const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int(&)[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int>,volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int&>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int&&>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int(&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int(&&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int>, const volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int&>, volatile const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int[2]>, const volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int(&)[2]>, volatile const int[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_reference_test.cpp b/ test/source/trait/remove_reference_test.cpp
@@ -0,0 +1,37 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/reference.hpp"
using based::SameAs;
TEST_CASE("remove_reference", "[trait/remove_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_reference_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int&>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int&&>, int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int&>, const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const int(&)[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int>,volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int&>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int&&>, volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int(&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<volatile int(&&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int>, const volatile int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int&>, volatile const int>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int[2]>, const volatile int[2]>);
STATIC_REQUIRE(SameAs<based::remove_reference_t<const volatile int(&)[2]>, volatile const int[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_volatile.cpp b/ test/source/trait/remove_volatile.cpp
@@ -1,37 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/volatile.hpp"
using based::SameAs;
TEST_CASE("remove_volatile", "[trait/remove/remove_volatile]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/remove_volatile_test.cpp b/ test/source/trait/remove_volatile_test.cpp
@@ -0,0 +1,37 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/trait/remove/volatile.hpp"
using based::SameAs;
TEST_CASE("remove_volatile", "[trait/remove/remove_volatile]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int>, int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int&>, int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int>, const int>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::remove_volatile_t<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}
diff --git a/ test/source/trait/signature_test.cpp b/ test/source/trait/signature_test.cpp
@@ -1,480 +0,0 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include "based/trait/signature.hpp"
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
// NOLINTBEGIN(*cognitive-complexity*)
namespace
{
// NOLINTNEXTLINE (*needed*)
int free_func(const double& a, int&& b) noexcept(false)
{
return static_cast<int>(a + b);
}
// NOLINTNEXTLINE (*needed*)
int free_func_noexcept(const double& a, int&& b) noexcept(true)
{
return static_cast<int>(a + b);
}
} // namespace
using based::SameAs;
TEST_CASE("free function", "[trait/signature]")
{
using sig = based::signature<decltype(free_func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("free function noexcept", "[trait/signature]")
{
using sig = based::signature<decltype(free_func_noexcept)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("empty", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) & noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) & noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) && noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) && noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
// NOLINTEND(*cognitive-complexity*)
diff --git a/ test/source/trait/signature_test_test.cpp b/ test/source/trait/signature_test_test.cpp
@@ -0,0 +1,480 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include "based/trait/signature.hpp"
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
// NOLINTBEGIN(*cognitive-complexity*)
namespace
{
// NOLINTNEXTLINE (*needed*)
int free_func(const double& a, int&& b) noexcept(false)
{
return static_cast<int>(a + b);
}
// NOLINTNEXTLINE (*needed*)
int free_func_noexcept(const double& a, int&& b) noexcept(true)
{
return static_cast<int>(a + b);
}
} // namespace
using based::SameAs;
TEST_CASE("free function", "[trait/signature]")
{
using sig = based::signature<decltype(free_func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("free function noexcept", "[trait/signature]")
{
using sig = based::signature<decltype(free_func_noexcept)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("empty", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) & noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) & noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept lvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) && noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("volatile rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("const volatile rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile&& noexcept(false);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::noexcept_val>);
}
TEST_CASE("noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) && noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("volatile noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) volatile&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::false_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
TEST_CASE("const volatile noexcept rvalref", "[trait/signature]")
{
struct test
{
int func(const double& a, int&& b) const volatile&& noexcept(true);
};
using sig = based::signature<decltype(&test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), sig::sig_type>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, sig::arg_type>);
STATIC_REQUIRE(SameAs<int, sig::ret_type>);
STATIC_REQUIRE(SameAs<based::true_type, sig::const_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::volatile_val>);
STATIC_REQUIRE(SameAs<based::false_type, sig::lvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::rvalref_val>);
STATIC_REQUIRE(SameAs<based::true_type, sig::noexcept_val>);
}
// NOLINTEND(*cognitive-complexity*)