proxygen
if_constexpr.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 
18 
19 // Usage:
20 //
21 // PUSHMI_IF_CONSTEXPR((condition)(
22 // stmt1;
23 // stmt2;
24 // ) else (
25 // stmt3;
26 // stmt4;
27 // ))
28 //
29 // If the statements could potentially be ill-formed, you can give some
30 // part of the expression a dependent type by wrapping it in `id`. For
31 
45  #ifndef __has_attribute
46  #define PUSHMI_HAS_ATTRIBUTE(x) 0
47  #else
48  #define PUSHMI_HAS_ATTRIBUTE(x) __has_attribute(x)
49  #endif
50 
51  #ifndef __has_cpp_attribute
52  #define PUSHMI_HAS_CPP_ATTRIBUTE(x) 0
53  #else
54  #define PUSHMI_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
55  #endif
56 
57 #if PUSHMI_HAS_CPP_ATTRIBUTE(maybe_unused)
58 #define PUSHMI_MAYBE_UNUSED [[maybe_unused]]
59 #elif PUSHMI_HAS_ATTRIBUTE(__unused__) || __GNUC__
60 #define PUSHMI_MAYBE_UNUSED __attribute__((__unused__))
61 #else
62 #define PUSHMI_MAYBE_UNUSED
63 #endif
64 
65 // disable buggy compatibility warning about "requires" and "concept" being
66 // C++20 keywords.
67 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 5)
68 #define PUSHMI_PP_IGNORE_SHADOW_BEGIN \
69  _Pragma("GCC diagnostic push") \
70  _Pragma("GCC diagnostic ignored \"-Wshadow\"") \
71 
72 #define PUSHMI_PP_IGNORE_SHADOW_END \
73  _Pragma("GCC diagnostic pop")
74 #else
75 
76 #define PUSHMI_PP_IGNORE_SHADOW_BEGIN
77 #define PUSHMI_PP_IGNORE_SHADOW_END
78 #endif
79 
80 #define PUSHMI_COMMA ,
81 
82 #define PUSHMI_EVAL(F, ...) F(__VA_ARGS__)
83 
84 #define PUSHMI_STRIP(...) __VA_ARGS__
85 
86 namespace folly {
87 namespace pushmi {
88 namespace detail {
89 struct id_fn {
90  constexpr explicit operator bool() const noexcept {
91  return false;
92  }
93  template <class T>
94  constexpr T&& operator()(T&& t) const noexcept {
95  return (T&&) t;
96  }
97 };
98 } // namespace detail
99 } // namespace pushmi
100 } // namespace folly
101 
102 #if __cpp_if_constexpr >= 201606
103 
104 #define PUSHMI_IF_CONSTEXPR(LIST) \
105  if constexpr (::folly::pushmi::detail::id_fn id = {}) { \
106  } else if constexpr \
107  PUSHMI_EVAL(PUSHMI_IF_CONSTEXPR_ELSE_, PUSHMI_IF_CONSTEXPR_IF_ LIST)
108 
109 #define PUSHMI_IF_CONSTEXPR_RETURN(LIST)\
110  PUSHMI_PP_IGNORE_SHADOW_BEGIN \
111  PUSHMI_IF_CONSTEXPR(LIST)\
112  PUSHMI_PP_IGNORE_SHADOW_END \
113 
114 
115 #define PUSHMI_IF_CONSTEXPR_IF_(...) \
116  (__VA_ARGS__) PUSHMI_COMMA PUSHMI_IF_CONSTEXPR_THEN_
117 
118 #define PUSHMI_IF_CONSTEXPR_THEN_(...) \
119  ({__VA_ARGS__}) PUSHMI_COMMA
120 
121 #define PUSHMI_IF_CONSTEXPR_ELSE_(A, B, C) \
122  A PUSHMI_STRIP B PUSHMI_IF_CONSTEXPR_ ## C
123 
124 #define PUSHMI_IF_CONSTEXPR_else(...) \
125  else {__VA_ARGS__}
126 
127 #else
128 
129 #include <type_traits>
130 
131 #define PUSHMI_IF_CONSTEXPR(LIST)\
132  PUSHMI_EVAL(PUSHMI_IF_CONSTEXPR_ELSE_, PUSHMI_IF_CONSTEXPR_IF_ LIST)\
133 
134 
135 #define PUSHMI_IF_CONSTEXPR_RETURN(LIST)\
136  return PUSHMI_EVAL(PUSHMI_IF_CONSTEXPR_ELSE_, PUSHMI_IF_CONSTEXPR_IF_ LIST)\
137 
138 
139 #define PUSHMI_IF_CONSTEXPR_IF_(...) \
140  (::folly::pushmi::detail::select<bool(__VA_ARGS__)>() ->* PUSHMI_IF_CONSTEXPR_THEN_ \
141 
142 
143 #define PUSHMI_IF_CONSTEXPR_THEN_(...) \
144  ([&](PUSHMI_MAYBE_UNUSED auto id)mutable->decltype(auto){__VA_ARGS__})) PUSHMI_COMMA \
145 
146 
147 #define PUSHMI_IF_CONSTEXPR_ELSE_(A, B) \
148  A ->* PUSHMI_IF_CONSTEXPR_ ## B \
149 
150 
151 #define PUSHMI_IF_CONSTEXPR_else(...) \
152  ([&](PUSHMI_MAYBE_UNUSED auto id)mutable->decltype(auto){__VA_ARGS__});\
153 
154 
155 namespace folly {
156 namespace pushmi {
157 namespace detail {
158 
159 template <bool>
160 struct select {
162  struct eat_return {
164  template <class T>
165  constexpr R operator->*(T&&) {
166  return static_cast<R&&>(value_);
167  }
168  };
169  struct eat {
170  template <class T>
171  constexpr void operator->*(T&&) {}
172  };
173  template <class T>
174  constexpr auto operator->*(T&& t)
175  -> eat_return<decltype(t(::folly::pushmi::detail::id_fn{}))> {
176  return {t(::folly::pushmi::detail::id_fn{})};
177  }
178  template <class T>
179  constexpr auto operator->*(T&& t) const -> eat {
180  return t(::folly::pushmi::detail::id_fn{}), void(), eat{};
181  }
182 };
183 
184 template <>
185 struct select<false> {
186  struct eat {
187  template <class T>
188  constexpr auto operator->*(T&& t) -> decltype(auto) {
189  return t(::folly::pushmi::detail::id_fn{});
190  }
191  };
192  template <class T>
193  constexpr eat operator->*(T&&) {
194  return {};
195  }
196 };
197 } // namespace detail
198 } // namespace pushmi
199 } // namespace folly
200 #endif
constexpr auto operator->*(T &&t) -> eat_return< decltype(t(::folly::pushmi::detail::id_fn
Definition: if_constexpr.h:174
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
constexpr T && operator()(T &&t) const noexcept
Definition: if_constexpr.h:94
constexpr auto operator->*(T &&t) const -> eat
Definition: if_constexpr.h:179
static const char *const value
Definition: Conv.cpp:50
constexpr auto operator->*(T &&t) -> decltype(auto)
Definition: if_constexpr.h:188
constexpr void operator->*(T &&)
Definition: if_constexpr.h:171
const
Definition: upload.py:398