proxygen
properties.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
19 
20 namespace folly {
21 namespace pushmi {
22 
23 // property_set implements a map of category-type to property-type.
24 // for each category only one property in that category is allowed in the set.
25 
26 // customization point for a property with a category
27 
28 template <class T>
29 using __property_category_t = typename T::property_category;
30 
31 // allow specializations to use enable_if to constrain
32 template <class T, class>
33 struct property_traits {};
34 template <class T>
36  T,
37  std::enable_if_t<Valid<std::decay_t<T>, __property_category_t>>> {
39 };
40 
41 template <class T>
43 
45  template(class T)
47  Valid<T, property_category_t>
48 );
49 
50 // in cases where Set contains T, allow T to find itself only once
52  template(class T, class... Set)(
53 concept FoundExactlyOnce)(T, Set...),
54  sum_v<(PUSHMI_PP_IS_SAME(T, Set) ? 1 : 0)...> == 1
55 );
56 
58  template(class... PropertyN)(
59 concept UniqueCategory)(PropertyN...),
60  And<FoundExactlyOnce<
62  property_category_t<PropertyN>...>...>&& And<Property<PropertyN>...>
63 );
64 
65 namespace detail {
66 template <PUSHMI_TYPE_CONSTRAINT(Property) P, class = property_category_t<P>>
68 } // namespace detail
69 
70 template <class... PropertyN>
71 struct property_set : detail::property_set_element<PropertyN>... {
72  static_assert(
73  and_v<Property<PropertyN>...>,
74  "property_set only supports types that match the Property concept");
75  static_assert(
76  UniqueCategory<PropertyN...>,
77  "property_set has multiple properties from the same category");
79 };
80 
82  template(class T)
83 concept PropertySet,
84  detail::is_v<T, property_set>
85 );
86 
87 // customization point for a type with properties
88 
89 template <class T>
90 using __properties_t = typename T::properties;
91 
92 // allow specializations to use enable_if to constrain
93 template <class T, class>
94 struct property_set_traits {};
95 template <class T>
97  T,
98  std::enable_if_t<Valid<std::decay_t<T>, __properties_t>>> {
100 };
101 
102 template <class T>
103 using properties_t = std::enable_if_t<
104  PropertySet<__properties_t<property_set_traits<T>>>,
106 
108  template(class T)
109 concept Properties,
110  Valid<T, properties_t>
111 );
112 
113 // find property in the specified set that matches the category of the property
114 // specified.
115 namespace detail {
116 template <class PIn, class POut>
118  property_set_element<POut, property_category_t<PIn>>);
119 
120 template <class PIn, class POut, class... Ps>
124  property_set_element<POut, property_category_t<PIn>>);
125 
126 template <class PIn, class... Ps>
128 
129 template <class PS, class P>
131  decltype(detail::__property_set_insert_fn<P>(PS{}, PS{}));
132 
133 template <class PS0, class>
135  using type = PS0;
136 };
137 
138 template <class PS0, class P, class... P1>
141  property_set_insert_one_t<PS0, P>,
142  property_set<P1...>> {};
143 } // namespace detail
144 
145 template <class PS, class P>
146 using property_set_index_t = std::enable_if_t<
147  PropertySet<PS> && Property<P>,
148  decltype(detail::__property_set_index_fn<P>(PS{}))>;
149 
150 template <class PS0, class PS1>
151 using property_set_insert_t = typename std::enable_if_t<
152  PropertySet<PS0> && PropertySet<PS1>,
154 
155 // query for properties on types with properties.
156 
157 namespace detail {
158 template <class PIn, class POut>
159 std::is_base_of<PIn, POut> property_query_fn(
160  property_set_element<POut, property_category_t<PIn>>*);
161 template <class PIn>
163 
164 template <class PS, class... ExpectedN>
165 struct property_query_impl : bool_<and_v<decltype(property_query_fn<ExpectedN>(
166  (properties_t<PS>*)nullptr))::value...>> {};
167 } // namespace detail
168 
169 template <class PS, class... ExpectedN>
170 struct property_query : std::conditional_t<
171  Properties<PS> && And<Property<ExpectedN>...>,
172  detail::property_query_impl<PS, ExpectedN...>,
173  std::false_type> {};
174 
175 template <class PS, class... ExpectedN>
177  property_query<PS, ExpectedN...>::value;
178 
179 // query for categories on types with properties.
180 
181 namespace detail {
182 template <class CIn, class POut>
183 std::true_type category_query_fn(property_set_element<POut, CIn>*);
184 template <class C>
186 
187 template <class PS, class... ExpectedN>
188 struct category_query_impl : bool_<and_v<decltype(category_query_fn<ExpectedN>(
189  (properties_t<PS>*)nullptr))::value...>> {};
190 } // namespace detail
191 
192 template <class PS, class... ExpectedN>
193 struct category_query : std::conditional_t<
194  Properties<PS> && not Or<Property<ExpectedN>...>,
195  detail::category_query_impl<PS, ExpectedN...>,
196  std::false_type> {};
197 
198 template <class PS, class... ExpectedN>
200  category_query<PS, ExpectedN...>::value;
201 
202 } // namespace pushmi
203 } // namespace folly
PUSHMI_INLINE_VAR constexpr bool and_v
Definition: traits.h:62
PUSHMI_INLINE_VAR constexpr bool category_query_v
Definition: properties.h:199
PskType type
#define P1(a, b)
std::enable_if_t< PropertySet< __properties_t< property_set_traits< T >>>, __properties_t< property_set_traits< T >>> properties_t
Definition: properties.h:105
STL namespace.
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::false_type category_query_fn(void *)
typename std::enable_if_t< PropertySet< PS0 > &&PropertySet< PS1 >, detail::property_set_insert< PS0, PS1 >>::type property_set_insert_t
Definition: properties.h:153
bool_constant< true > true_type
Definition: gtest-port.h:2210
#define PUSHMI_PP_IS_SAME(...)
Definition: concept_def.h:68
PUSHMI_INLINE_VAR constexpr bool property_query_v
Definition: properties.h:176
PUSHMI_INLINE_VAR constexpr int sum_v
Definition: traits.h:71
__property_category_t< property_traits< T >> property_category_t
Definition: properties.h:42
PUSHMI_CONCEPT_DEF(template(class PS) concept Cardinality, has_cardinality_v< PS >)
std::false_type property_query_fn(void *)
#define concept
std::enable_if_t< PropertySet< PS > &&Property< P >, decltype(detail::__property_set_index_fn< P >(PS{}))> property_set_index_t
Definition: properties.h:148
decltype(detail::__property_set_insert_fn< P >(PS{}, PS{})) property_set_insert_one_t
Definition: properties.h:131
#define PUSHMI_INLINE_VAR
Definition: concept_def.h:60
PolymorphicMatcher< internal::PropertyMatcher< Class, PropertyType > > Property(PropertyType(Class::*property)() const, const PropertyMatcher &matcher)
std::integral_constant< bool, B > bool_
Definition: concept_def.h:443
property_set< Ps..., PIn > __property_set_insert_fn(property_set< Ps... >,...)
typename T::property_category __property_category_t
Definition: properties.h:29
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
Definition: gtest-port.h:2209
POut __property_set_index_fn(property_set_element< POut, property_category_t< PIn >>)
typename T::properties __properties_t
Definition: properties.h:90