- Switched from Allman (BSD) to 1TBS (K&R)
Namespaces, Types, and Requires/Concepts still use Allman
This commit is contained in:
@@ -69,8 +69,9 @@ extern void __assert_impl(const char* expression, const char* file, int line, co
|
||||
|
||||
// flagged unlikely to optimize branch prediction
|
||||
#define assert(expression, description) \
|
||||
if(not(expression)) [[unlikely]] \
|
||||
{ __assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description); }
|
||||
if(not(expression)) [[unlikely]] { \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description); \
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertd(expression, description) (0)
|
||||
|
||||
@@ -95,12 +95,10 @@ namespace fennec
|
||||
/// \param from Value to bit cast
|
||||
/// \returns A value containing a bitwise copy of the input
|
||||
template<typename ToT, typename FromT> requires(sizeof(ToT) == sizeof(FromT))
|
||||
constexpr ToT bit_cast(const FromT& from)
|
||||
{
|
||||
if constexpr(FENNEC_HAS_BUILTIN_BIT_CAST)
|
||||
constexpr ToT bit_cast(const FromT& from) {
|
||||
if constexpr(FENNEC_HAS_BUILTIN_BIT_CAST) {
|
||||
return FENNEC_BUILTIN_BIT_CAST(ToT, from);
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ToT to;
|
||||
fennec::memcpy(&to, &from, sizeof(ToT));
|
||||
return to;
|
||||
@@ -119,14 +117,15 @@ constexpr ToT bit_cast(const FromT& from)
|
||||
/// \param mask the mask to and against arr
|
||||
/// \param n the number of bytes
|
||||
/// \returns the pointer \f$arr\f$
|
||||
constexpr void* bit_and(void* arr, const void* mask, size_t n)
|
||||
{
|
||||
if (arr == mask) return arr;
|
||||
constexpr void* bit_and(void* arr, const void* mask, size_t n) {
|
||||
if (arr == mask) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
uint8_t* d = static_cast<uint8_t*>(arr);
|
||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
while (n > 0) {
|
||||
size_t step = detail::__bit_and(d, s, n);
|
||||
d += step; s += step; n -= step;
|
||||
}
|
||||
@@ -143,8 +142,9 @@ constexpr void* bit_and(void* arr, const void* mask, size_t n)
|
||||
/// \param mask the mask to and against arr
|
||||
/// \param n1 the size of mask in bytes
|
||||
/// \returns the pointer arr
|
||||
constexpr void* bit_and_s(void* arr, size_t n0, const void* mask, size_t n1)
|
||||
{ return bit_and(arr, mask, n0 < n1 ? n0 : n1); }
|
||||
constexpr void* bit_and_s(void* arr, size_t n0, const void* mask, size_t n1) {
|
||||
return bit_and(arr, mask, n0 < n1 ? n0 : n1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -158,12 +158,13 @@ constexpr void* bit_and_s(void* arr, size_t n0, const void* mask, size_t n1)
|
||||
/// \param mask the mask to or against arr
|
||||
/// \param n the number of bytes
|
||||
/// \returns the pointer arr
|
||||
constexpr void* bit_or(void* arr, const void* mask, size_t n)
|
||||
{
|
||||
if (arr == mask) return arr;
|
||||
constexpr void* bit_or(void* arr, const void* mask, size_t n) {
|
||||
if (arr == mask) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
uint8_t* d = static_cast<uint8_t*>(arr);
|
||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
size_t step = detail::__bit_or(d, s, n);
|
||||
@@ -182,8 +183,9 @@ constexpr void* bit_or(void* arr, const void* mask, size_t n)
|
||||
/// \param mask the mask to or against arr
|
||||
/// \param n1 the size of mask in bytes
|
||||
/// \returns the pointer arr
|
||||
constexpr void* bit_or_s(void* arr, size_t n0, const void* mask, size_t n1)
|
||||
{ return bit_or(arr, mask, n0 < n1 ? n0 : n1); }
|
||||
constexpr void* bit_or_s(void* arr, size_t n0, const void* mask, size_t n1) {
|
||||
return bit_or(arr, mask, n0 < n1 ? n0 : n1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -197,14 +199,14 @@ constexpr void* bit_or_s(void* arr, size_t n0, const void* mask, size_t n1)
|
||||
/// \param mask the mask to or against arr
|
||||
/// \param n the number of bytes
|
||||
/// \returns the pointer arr
|
||||
constexpr void* bit_xor(void* arr, const void* mask, size_t n)
|
||||
{
|
||||
if (arr == mask) return arr;
|
||||
constexpr void* bit_xor(void* arr, const void* mask, size_t n) {
|
||||
if (arr == mask) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
uint8_t* d = static_cast<uint8_t*>(arr);
|
||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
while (n > 0) {
|
||||
size_t step = detail::__bit_xor(d, s, n);
|
||||
d += step; s += step; n -= step;
|
||||
}
|
||||
@@ -221,8 +223,9 @@ constexpr void* bit_xor(void* arr, const void* mask, size_t n)
|
||||
/// \param mask the mask to or against arr
|
||||
/// \param n1 the size of mask in bytes
|
||||
/// \returns the pointer arr
|
||||
constexpr void* bit_xor_s(void* arr, size_t n0, const void* mask, size_t n1)
|
||||
{ return bit_xor(arr, mask, n0 < n1 ? n0 : n1); }
|
||||
constexpr void* bit_xor_s(void* arr, size_t n0, const void* mask, size_t n1) {
|
||||
return bit_xor(arr, mask, n0 < n1 ? n0 : n1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,12 @@ using conditional_t
|
||||
|
||||
// specialization of fennec::conditional for `true` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<true, T, F>
|
||||
: type_transform<T>{};
|
||||
struct conditional<true, T, F> : type_transform<T>{};
|
||||
|
||||
|
||||
// specialization of fennec::conditional for `false` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<false, T, F>
|
||||
: type_transform<F>{};
|
||||
struct conditional<false, T, F> : type_transform<F>{};
|
||||
|
||||
|
||||
// fennec::detect ======================================================================================================
|
||||
@@ -122,8 +120,7 @@ struct detect
|
||||
///
|
||||
/// \brief Shorthand for ```typename detect<DefaultT, DetectT, ArgsT...>::type```
|
||||
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
|
||||
using detect_t
|
||||
= typename detect<DefaultT, DetectT, ArgsT...>::type;
|
||||
using detect_t = typename detect<DefaultT, DetectT, ArgsT...>::type;
|
||||
|
||||
|
||||
// true case
|
||||
@@ -133,7 +130,6 @@ struct detect<DefaultT, DetectT, ArgsT...>
|
||||
{
|
||||
using type = DetectT<ArgsT...>;
|
||||
static constexpr bool is_detected = true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,26 +28,28 @@ namespace detail
|
||||
{
|
||||
|
||||
// helper for bitwise and for 1 byte
|
||||
constexpr size_t __bit_and_8(void* dst, const void* src)
|
||||
{ *static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) & *static_cast<const uint8_t*>(src); return 1; }
|
||||
constexpr size_t __bit_and_8(void* dst, const void* src) {
|
||||
*static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) & *static_cast<const uint8_t*>(src); return 1;
|
||||
}
|
||||
|
||||
// helper for bitwise and 2 bytes at once
|
||||
constexpr size_t __bit_and_16(void* dst, const void* src)
|
||||
{ *static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) & *static_cast<const uint16_t*>(src); return 2; }
|
||||
constexpr size_t __bit_and_16(void* dst, const void* src) {
|
||||
*static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) & *static_cast<const uint16_t*>(src); return 2;
|
||||
}
|
||||
|
||||
// helper for bitwise and 4 bytes at once
|
||||
constexpr size_t __bit_and_32(void* dst, const void* src)
|
||||
{ *static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) & *static_cast<const uint32_t*>(src); return 4; }
|
||||
constexpr size_t __bit_and_32(void* dst, const void* src) {
|
||||
*static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) & *static_cast<const uint32_t*>(src); return 4;
|
||||
}
|
||||
|
||||
// helper for bitwise and 8 bytes at once
|
||||
constexpr size_t __bit_and_64(void* dst, const void* src)
|
||||
{ *static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) & *static_cast<const uint64_t*>(src); return 8; }
|
||||
constexpr size_t __bit_and_64(void* dst, const void* src) {
|
||||
*static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) & *static_cast<const uint64_t*>(src); return 8;
|
||||
}
|
||||
|
||||
// helper for selecting size
|
||||
constexpr size_t __bit_and(void* dst, const void* src, size_t n)
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
constexpr size_t __bit_and(void* dst, const void* src, size_t n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
@@ -63,26 +65,28 @@ constexpr size_t __bit_and(void* dst, const void* src, size_t n)
|
||||
|
||||
|
||||
// helper for bitwise or for 1 byte
|
||||
constexpr size_t __bit_or_8(void* dst, const void* src)
|
||||
{ *static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) | *static_cast<const uint8_t*>(src); return 1; }
|
||||
constexpr size_t __bit_or_8(void* dst, const void* src) {
|
||||
*static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) | *static_cast<const uint8_t*>(src); return 1;
|
||||
}
|
||||
|
||||
// helper for bitwise or 2 bytes at once
|
||||
constexpr size_t __bit_or_16(void* dst, const void* src)
|
||||
{ *static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) | *static_cast<const uint16_t*>(src); return 2; }
|
||||
constexpr size_t __bit_or_16(void* dst, const void* src) {
|
||||
*static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) | *static_cast<const uint16_t*>(src); return 2;
|
||||
}
|
||||
|
||||
// helper for bitwise or 4 bytes at once
|
||||
constexpr size_t __bit_or_32(void* dst, const void* src)
|
||||
{ *static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) | *static_cast<const uint32_t*>(src); return 4; }
|
||||
constexpr size_t __bit_or_32(void* dst, const void* src) {
|
||||
*static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) | *static_cast<const uint32_t*>(src); return 4;
|
||||
}
|
||||
|
||||
// helper for bitwise or 8 bytes at once
|
||||
constexpr size_t __bit_or_64(void* dst, const void* src)
|
||||
{ *static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) | *static_cast<const uint64_t*>(src); return 8; }
|
||||
constexpr size_t __bit_or_64(void* dst, const void* src) {
|
||||
*static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) | *static_cast<const uint64_t*>(src); return 8;
|
||||
}
|
||||
|
||||
// helper for selecting size
|
||||
constexpr size_t __bit_or(void* dst, const void* src, size_t n)
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
constexpr size_t __bit_or(void* dst, const void* src, size_t n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
@@ -98,26 +102,28 @@ constexpr size_t __bit_or(void* dst, const void* src, size_t n)
|
||||
|
||||
|
||||
// helper for bitwise and 1 byte
|
||||
constexpr size_t __bit_xor_8(void* dst, const void* src)
|
||||
{ *static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) ^ *static_cast<const uint8_t*>(src); return 1; }
|
||||
constexpr size_t __bit_xor_8(void* dst, const void* src) {
|
||||
*static_cast<uint8_t*>(dst) = *static_cast<uint8_t*>(dst) ^ *static_cast<const uint8_t*>(src); return 1;
|
||||
}
|
||||
|
||||
// helper for bitwise xor 2 bytes at once
|
||||
constexpr size_t __bit_xor_16(void* dst, const void* src)
|
||||
{ *static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) ^ *static_cast<const uint16_t*>(src); return 2; }
|
||||
constexpr size_t __bit_xor_16(void* dst, const void* src) {
|
||||
*static_cast<uint16_t*>(dst) = *static_cast<uint16_t*>(dst) ^ *static_cast<const uint16_t*>(src); return 2;
|
||||
}
|
||||
|
||||
// helper for bitwise xor 4 bytes at once
|
||||
constexpr size_t __bit_xor_32(void* dst, const void* src)
|
||||
{ *static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) ^ *static_cast<const uint32_t*>(src); return 4; }
|
||||
constexpr size_t __bit_xor_32(void* dst, const void* src) {
|
||||
*static_cast<uint32_t*>(dst) = *static_cast<uint32_t*>(dst) ^ *static_cast<const uint32_t*>(src); return 4;
|
||||
}
|
||||
|
||||
// helper for bitwise xor 8 bytes at once
|
||||
constexpr size_t __bit_xor_64(void* dst, const void* src)
|
||||
{ *static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) ^ *static_cast<const uint64_t*>(src); return 8; }
|
||||
constexpr size_t __bit_xor_64(void* dst, const void* src) {
|
||||
*static_cast<uint64_t*>(dst) = *static_cast<uint64_t*>(dst) ^ *static_cast<const uint64_t*>(src); return 8;
|
||||
}
|
||||
|
||||
// helper for selecting size
|
||||
constexpr size_t __bit_xor(void* dst, const void* src, size_t n)
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
constexpr size_t __bit_xor(void* dst, const void* src, size_t n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
|
||||
@@ -103,7 +103,9 @@ template<typename ValueT, ValueT...Values> struct sequence
|
||||
/// \brief returns the number of elements
|
||||
///
|
||||
/// \return number of elements in the array
|
||||
inline static constexpr size_t size() noexcept { return sizeof...(Values); }
|
||||
inline static constexpr size_t size() noexcept {
|
||||
return sizeof...(Values);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -129,7 +131,9 @@ struct integer_sequence : sequence<IntT, Values...>
|
||||
/// \brief returns the number of elements
|
||||
///
|
||||
/// \return number of elements in the array
|
||||
inline static constexpr size_t size() noexcept { return sizeof...(Values); }
|
||||
inline static constexpr size_t size() noexcept {
|
||||
return sizeof...(Values);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -166,7 +170,9 @@ template<size_t...Indices> struct index_sequence : integer_sequence<size_t, Indi
|
||||
/// \brief returns the number of elements
|
||||
///
|
||||
/// \return number of elements in the array
|
||||
inline static constexpr size_t size() noexcept { return sizeof...(Indices); }
|
||||
inline static constexpr size_t size() noexcept {
|
||||
return sizeof...(Indices);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -125,8 +125,7 @@ template<typename T> struct is_void
|
||||
///
|
||||
/// \brief shorthand for ```is_void<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_void_v
|
||||
= is_void<T>::value;
|
||||
template<typename T> constexpr bool_t is_void_v = is_void<T>::value;
|
||||
|
||||
|
||||
|
||||
@@ -143,8 +142,7 @@ template<typename T> struct is_bool
|
||||
///
|
||||
/// \brief shorthand for ```is_bool<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_bool_v
|
||||
= is_bool<T>::value;
|
||||
template<typename T> constexpr bool_t is_bool_v = is_bool<T>::value;
|
||||
|
||||
|
||||
|
||||
@@ -161,8 +159,7 @@ template<typename T> struct is_null_pointer
|
||||
///
|
||||
/// \brief shorthand for ```is_null_pointer<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_null_pointer_v
|
||||
= is_null_pointer<T>::value;
|
||||
template<typename T> constexpr bool_t is_null_pointer_v = is_null_pointer<T>::value;
|
||||
|
||||
|
||||
|
||||
@@ -197,8 +194,7 @@ template<typename T> struct is_array<T[]>
|
||||
///
|
||||
/// \brief shorthand for ```is_array<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_array_v
|
||||
= is_array<T>::value;
|
||||
template<typename T> constexpr bool_t is_array_v = is_array<T>::value;
|
||||
|
||||
// fennec::is_class ====================================================================================================
|
||||
|
||||
@@ -211,8 +207,7 @@ template<typename T> struct is_class
|
||||
///
|
||||
/// \brief check if \p T is a class
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr size_t is_class_v
|
||||
= is_class<T>::value;
|
||||
template<typename T> constexpr size_t is_class_v = is_class<T>::value;
|
||||
|
||||
|
||||
|
||||
@@ -229,8 +224,7 @@ template<typename T> struct is_integral
|
||||
///
|
||||
/// \brief shorthand for ```is_integral<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_integral_v
|
||||
= is_integral<T>::value;
|
||||
template<typename T> constexpr bool_t is_integral_v = is_integral<T>::value;
|
||||
|
||||
|
||||
///
|
||||
@@ -244,8 +238,7 @@ template<typename T> struct is_signed
|
||||
///
|
||||
/// \brief shorthand for ```is_signed<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_signed_v
|
||||
= is_signed<T>::value;
|
||||
template<typename T> constexpr bool_t is_signed_v = is_signed<T>::value;
|
||||
|
||||
|
||||
///
|
||||
@@ -259,8 +252,7 @@ template<typename T> struct is_unsigned
|
||||
///
|
||||
/// \brief shorthand for ```is_unsigned<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_unsigned_v
|
||||
= is_unsigned<T>::value;
|
||||
template<typename T> constexpr bool_t is_unsigned_v = is_unsigned<T>::value;
|
||||
|
||||
|
||||
|
||||
@@ -277,8 +269,7 @@ template<typename T> struct is_floating_point
|
||||
///
|
||||
/// \brief shorthand for ```is_floating_point<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_floating_point_v
|
||||
= is_floating_point<T> {};
|
||||
template<typename T> constexpr bool_t is_floating_point_v = is_floating_point<T> {};
|
||||
|
||||
|
||||
|
||||
@@ -295,8 +286,7 @@ template<typename T> struct is_arithmetic
|
||||
///
|
||||
/// \brief shorthand for ```is_arithmetic<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_arithmetic_v
|
||||
= is_arithmetic<T>::value;
|
||||
template<typename T> constexpr bool_t is_arithmetic_v = is_arithmetic<T>::value;
|
||||
|
||||
// fennec::is_same =====================================================================================================
|
||||
|
||||
@@ -306,18 +296,15 @@ template<typename T> constexpr bool_t is_arithmetic_v
|
||||
/// \details Checks if `T0` and `T1` are identical and store it in `is_same::value`
|
||||
/// \tparam T0 first type to check
|
||||
/// \tparam T1 second type to check
|
||||
template<typename T0, typename T1> struct is_same
|
||||
: false_type {};
|
||||
template<typename T0, typename T1> struct is_same : false_type {};
|
||||
|
||||
// true case
|
||||
template<typename T> struct is_same<T, T>
|
||||
: true_type {};
|
||||
template<typename T> struct is_same<T, T> : true_type {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_same<T0, T1>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T0, typename T1> constexpr bool_t is_same_v
|
||||
= is_same<T0, T1> {};
|
||||
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
|
||||
|
||||
// fennec::can_convert =================================================================================================
|
||||
|
||||
@@ -334,8 +321,7 @@ template<typename FromT, typename ToT> struct is_convertible
|
||||
/// \brief shorthand for `can_convert<TypeT0, TypeT1>::value`
|
||||
/// \param FromT First type
|
||||
/// \param ToT Second type
|
||||
template<typename FromT, typename ToT> constexpr bool_t is_convertible_v
|
||||
= is_convertible<FromT, ToT>{};
|
||||
template<typename FromT, typename ToT> constexpr bool_t is_convertible_v = is_convertible<FromT, ToT>{};
|
||||
|
||||
|
||||
// fennec::is_constructible ===============================================================================================
|
||||
@@ -350,8 +336,7 @@ template<typename ClassT, typename...ArgsT> struct is_constructible
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_constructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_constructible_v
|
||||
= is_constructible<ClassT, ArgsT...>{};
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_constructible_v = is_constructible<ClassT, ArgsT...>{};
|
||||
|
||||
|
||||
// fennec::
|
||||
|
||||
@@ -71,10 +71,14 @@ namespace fennec
|
||||
/// \tparam T base type of the object
|
||||
/// \param x reference to the object
|
||||
/// \returns
|
||||
template<typename T> constexpr T&& forward(remove_reference_t<T>& x) noexcept { return static_cast<T&&>(x); }
|
||||
template<typename T> constexpr T&& forward(remove_reference_t<T>& x) noexcept {
|
||||
return static_cast<T&&>(x);
|
||||
}
|
||||
|
||||
// specialization for T&&
|
||||
template<typename T> constexpr T&& forward(remove_reference_t<T>&& x) noexcept { return static_cast<T&&>(x); }
|
||||
template<typename T> constexpr T&& forward(remove_reference_t<T>&& x) noexcept {
|
||||
return static_cast<T&&>(x);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
@@ -84,7 +88,9 @@ template<typename T> constexpr T&& forward(remove_reference_t<T>&& x) noexcept {
|
||||
/// \tparam T base type of the object
|
||||
/// \param x object to be moved
|
||||
/// \returns `static_cast<remove_reference_t<T>&&>(x)`
|
||||
template<typename T> constexpr remove_reference_t<T>&& move(T&& x) noexcept { return static_cast<remove_reference_t<T>&&>(x); }
|
||||
template<typename T> constexpr remove_reference_t<T>&& move(T&& x) noexcept {
|
||||
return static_cast<remove_reference_t<T>&&>(x);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
@@ -94,7 +100,9 @@ template<typename T> constexpr remove_reference_t<T>&& move(T&& x) noexcept { re
|
||||
/// \tparam T base type of the object
|
||||
/// \param x object to be copied
|
||||
/// \returns const r-value
|
||||
template<typename T> constexpr const remove_reference_t<T>& copy(T&& x) noexcept { return x; }
|
||||
template<typename T> constexpr const remove_reference_t<T>& copy(T&& x) noexcept {
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user