add cvref_traits utility

This commit is contained in:
BlackMATov
2022-01-07 13:54:37 +07:00
parent ff1fb1fbd7
commit ee273b1f55
2 changed files with 109 additions and 0 deletions

View File

@@ -9,6 +9,31 @@
#include "meta_base.hpp"
#include "meta_types.hpp"
namespace meta_hpp::detail
{
template < typename From >
struct cvref_traits {
static constexpr bool is_lvalue = std::is_lvalue_reference_v<From>;
static constexpr bool is_rvalue = std::is_rvalue_reference_v<From>;
static constexpr bool is_const = std::is_const_v<std::remove_reference_t<From>>;
static constexpr bool is_volatile = std::is_volatile_v<std::remove_reference_t<From>>;
template < bool yesno, template < typename > typename Q, typename V >
using apply_t_if = std::conditional_t<yesno, Q<V>, V>;
template < typename To >
using copy_to =
apply_t_if<is_lvalue, std::add_lvalue_reference_t,
apply_t_if<is_rvalue, std::add_rvalue_reference_t,
apply_t_if<is_const, std::add_const_t,
apply_t_if<is_volatile, std::add_volatile_t,
std::remove_cvref_t<To>>>>>;
};
template < typename From, typename To >
using copy_cvref_t = typename cvref_traits<From>::template copy_to<To>;
}
namespace meta_hpp::detail
{
template < typename T >

View File

@@ -0,0 +1,84 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include "../meta_tests.hpp"
TEST_CASE("features/meta_utilities/detail") {
namespace meta = meta_hpp;
SUBCASE("cvref_traits") {
static_assert(!meta::detail::cvref_traits<int>::is_lvalue);
static_assert(!meta::detail::cvref_traits<int>::is_rvalue);
static_assert(!meta::detail::cvref_traits<int>::is_const);
static_assert(!meta::detail::cvref_traits<int>::is_volatile);
static_assert(!meta::detail::cvref_traits<const int>::is_lvalue);
static_assert(!meta::detail::cvref_traits<const int>::is_rvalue);
static_assert(meta::detail::cvref_traits<const int>::is_const);
static_assert(!meta::detail::cvref_traits<const int>::is_volatile);
static_assert(!meta::detail::cvref_traits<const volatile int>::is_lvalue);
static_assert(!meta::detail::cvref_traits<const volatile int>::is_rvalue);
static_assert(meta::detail::cvref_traits<const volatile int>::is_const);
static_assert(meta::detail::cvref_traits<const volatile int>::is_volatile);
static_assert(meta::detail::cvref_traits<int&>::is_lvalue);
static_assert(!meta::detail::cvref_traits<int&>::is_rvalue);
static_assert(!meta::detail::cvref_traits<int&>::is_const);
static_assert(!meta::detail::cvref_traits<int&>::is_volatile);
static_assert(meta::detail::cvref_traits<const int&>::is_lvalue);
static_assert(!meta::detail::cvref_traits<const int&>::is_rvalue);
static_assert(meta::detail::cvref_traits<const int&>::is_const);
static_assert(!meta::detail::cvref_traits<const int&>::is_volatile);
static_assert(meta::detail::cvref_traits<const volatile int&>::is_lvalue);
static_assert(!meta::detail::cvref_traits<const volatile int&>::is_rvalue);
static_assert(meta::detail::cvref_traits<const volatile int&>::is_const);
static_assert(meta::detail::cvref_traits<const volatile int&>::is_volatile);
static_assert(!meta::detail::cvref_traits<int&&>::is_lvalue);
static_assert(meta::detail::cvref_traits<int&&>::is_rvalue);
static_assert(!meta::detail::cvref_traits<int&&>::is_const);
static_assert(!meta::detail::cvref_traits<int&&>::is_volatile);
static_assert(!meta::detail::cvref_traits<const int&&>::is_lvalue);
static_assert(meta::detail::cvref_traits<const int&&>::is_rvalue);
static_assert(meta::detail::cvref_traits<const int&&>::is_const);
static_assert(!meta::detail::cvref_traits<const int&&>::is_volatile);
static_assert(!meta::detail::cvref_traits<const volatile int&&>::is_lvalue);
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_rvalue);
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_const);
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_volatile);
}
SUBCASE("cvref_traits::copy_to") {
static_assert(std::same_as<meta::detail::cvref_traits<float>::copy_to<int>, int>);
static_assert(std::same_as<meta::detail::cvref_traits<const float>::copy_to<int>, const int>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float>::copy_to<int>, const volatile int>);
static_assert(std::same_as<meta::detail::cvref_traits<float&>::copy_to<int>, int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const float&>::copy_to<int>, const int&>);
static_assert(std::same_as<meta::detail::cvref_traits<volatile float&>::copy_to<int>, volatile int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float&&>::copy_to<int>, const volatile int&&>);
static_assert(std::same_as<meta::detail::cvref_traits<float>::copy_to<int&>, int>);
static_assert(std::same_as<meta::detail::cvref_traits<const float>::copy_to<int&>, const int>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float>::copy_to<int&>, const volatile int>);
static_assert(std::same_as<meta::detail::cvref_traits<float&>::copy_to<int&>, int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const float&>::copy_to<int&>, const int&>);
static_assert(std::same_as<meta::detail::cvref_traits<volatile float&>::copy_to<int&>, volatile int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float&&>::copy_to<int&>, const volatile int&&>);
static_assert(std::same_as<meta::detail::cvref_traits<float>::copy_to<const volatile int&&>, int>);
static_assert(std::same_as<meta::detail::cvref_traits<const float>::copy_to<const volatile int&&>, const int>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float>::copy_to<const volatile int&&>, const volatile int>);
static_assert(std::same_as<meta::detail::cvref_traits<float&>::copy_to<const volatile int&&>, int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const float&>::copy_to<const volatile int&&>, const int&>);
static_assert(std::same_as<meta::detail::cvref_traits<volatile float&>::copy_to<const volatile int&&>, volatile int&>);
static_assert(std::same_as<meta::detail::cvref_traits<const volatile float&&>::copy_to<const volatile int&&>, const volatile int&&>);
}
}