Warning: That file was not part of the compilation database. It may have many parsing errors.

1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef TEST_SUPPORT_PROPAGATE_VALUE_CATEGORY
10#define TEST_SUPPORT_PROPAGATE_VALUE_CATEGORY
11
12#include "test_macros.h"
13#include <type_traits>
14
15#if TEST_STD_VER < 11
16#error this header may only be used in C++11
17#endif
18
19using UnderlyingVCType = unsigned;
20enum ValueCategory : UnderlyingVCType {
21 VC_None = 0,
22 VC_LVal = 1 << 0,
23 VC_RVal = 1 << 1,
24 VC_Const = 1 << 2,
25 VC_Volatile = 1 << 3,
26 VC_ConstVolatile = VC_Const | VC_Volatile
27};
28
29inline constexpr ValueCategory operator&(ValueCategory LHS, ValueCategory RHS) {
30 return ValueCategory(LHS & (UnderlyingVCType)RHS);
31}
32
33inline constexpr ValueCategory operator|(ValueCategory LHS, ValueCategory RHS) {
34 return ValueCategory(LHS | (UnderlyingVCType)RHS);
35}
36
37inline constexpr ValueCategory operator^(ValueCategory LHS, ValueCategory RHS) {
38 return ValueCategory(LHS ^ (UnderlyingVCType)RHS);
39}
40
41inline constexpr bool isValidValueCategory(ValueCategory VC) {
42 return (VC & (VC_LVal | VC_RVal)) != (VC_LVal | VC_RVal);
43}
44
45inline constexpr bool hasValueCategory(ValueCategory Arg, ValueCategory Key) {
46 return Arg == Key || ((Arg & Key) == Key);
47}
48
49template <class Tp>
50using UnCVRef =
51 typename std::remove_cv<typename std::remove_reference<Tp>::type>::type;
52
53template <class Tp>
54constexpr ValueCategory getReferenceQuals() {
55 return std::is_lvalue_reference<Tp>::value
56 ? VC_LVal
57 : (std::is_rvalue_reference<Tp>::value ? VC_RVal : VC_None);
58}
59static_assert(getReferenceQuals<int>() == VC_None, "");
60static_assert(getReferenceQuals<int &>() == VC_LVal, "");
61static_assert(getReferenceQuals<int &&>() == VC_RVal, "");
62
63template <class Tp>
64constexpr ValueCategory getCVQuals() {
65 using Vp = typename std::remove_reference<Tp>::type;
66 return std::is_const<Vp>::value && std::is_volatile<Vp>::value
67 ? VC_ConstVolatile
68 : (std::is_const<Vp>::value
69 ? VC_Const
70 : (std::is_volatile<Vp>::value ? VC_Volatile : VC_None));
71}
72static_assert(getCVQuals<int>() == VC_None, "");
73static_assert(getCVQuals<int const>() == VC_Const, "");
74static_assert(getCVQuals<int volatile>() == VC_Volatile, "");
75static_assert(getCVQuals<int const volatile>() == VC_ConstVolatile, "");
76static_assert(getCVQuals<int &>() == VC_None, "");
77static_assert(getCVQuals<int const &>() == VC_Const, "");
78
79template <class Tp>
80inline constexpr ValueCategory getValueCategory() {
81 return getReferenceQuals<Tp>() | getCVQuals<Tp>();
82}
83static_assert(getValueCategory<int>() == VC_None, "");
84static_assert(getValueCategory<int const &>() == (VC_LVal | VC_Const), "");
85static_assert(getValueCategory<int const volatile &&>() ==
86 (VC_RVal | VC_ConstVolatile),
87 "");
88
89template <ValueCategory VC>
90struct ApplyValueCategory {
91private:
92 static_assert(isValidValueCategory(VC), "");
93
94 template <bool Pred, class Then, class Else>
95 using CondT = typename std::conditional<Pred, Then, Else>::type;
96
97public:
98 template <class Tp, class Vp = UnCVRef<Tp>>
99 using ApplyCVQuals = CondT<
100 hasValueCategory(Arg: VC, Key: VC_ConstVolatile), typename std::add_cv<Vp>::type,
101 CondT<hasValueCategory(Arg: VC, Key: VC_Const), typename std::add_const<Vp>::type,
102 CondT<hasValueCategory(Arg: VC, Key: VC_Volatile),
103 typename std::add_volatile<Vp>::type, Tp>>>;
104
105 template <class Tp, class Vp = typename std::remove_reference<Tp>::type>
106 using ApplyReferenceQuals =
107 CondT<hasValueCategory(Arg: VC, Key: VC_LVal),
108 typename std::add_lvalue_reference<Vp>::type,
109 CondT<hasValueCategory(Arg: VC, Key: VC_RVal),
110 typename std::add_rvalue_reference<Vp>::type, Vp>>;
111
112 template <class Tp>
113 using Apply = ApplyReferenceQuals<ApplyCVQuals<UnCVRef<Tp>>>;
114
115 template <class Tp, bool Dummy = true,
116 typename std::enable_if<Dummy && (VC & VC_LVal), bool>::type = true>
117 static Apply<UnCVRef<Tp>> cast(Tp &&t) {
118 using ToType = Apply<UnCVRef<Tp>>;
119 return static_cast<ToType>(t);
120 }
121
122 template <class Tp, bool Dummy = true,
123 typename std::enable_if<Dummy && (VC & VC_RVal), bool>::type = true>
124 static Apply<UnCVRef<Tp>> cast(Tp &&t) {
125 using ToType = Apply<UnCVRef<Tp>>;
126 return static_cast<ToType>(std::move(t));
127 }
128
129 template <
130 class Tp, bool Dummy = true,
131 typename std::enable_if<Dummy && ((VC & (VC_LVal | VC_RVal)) == VC_None),
132 bool>::type = true>
133 static Apply<UnCVRef<Tp>> cast(Tp &&t) {
134 return t;
135 }
136};
137
138template <ValueCategory VC, class Tp>
139using ApplyValueCategoryT = typename ApplyValueCategory<VC>::template Apply<Tp>;
140
141template <class Tp>
142using PropagateValueCategory = ApplyValueCategory<getValueCategory<Tp>()>;
143
144template <class Tp, class Up>
145using PropagateValueCategoryT =
146 typename ApplyValueCategory<getValueCategory<Tp>()>::template Apply<Up>;
147
148template <ValueCategory VC, class Tp>
149typename ApplyValueCategory<VC>::template Apply<Tp> ValueCategoryCast(Tp &&t) {
150 return ApplyValueCategory<VC>::cast(std::forward<Tp>(t));
151};
152
153#endif // TEST_SUPPORT_PROPAGATE_VALUE_CATEGORY
154

Warning: That file was not part of the compilation database. It may have many parsing errors.

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libcxx/test/support/propagate_value_category.hpp