Utility.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * Copyright 2016-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. #include <cstdint>
  18. #include <limits>
  19. #include <type_traits>
  20. #include <utility>
  21. #include <folly/CPortability.h>
  22. #include <folly/Traits.h>
  23. namespace folly {
  24. /**
  25. * copy
  26. *
  27. * Usable when you have a function with two overloads:
  28. *
  29. * class MyData;
  30. * void something(MyData&&);
  31. * void something(const MyData&);
  32. *
  33. * Where the purpose is to make copies and moves explicit without having to
  34. * spell out the full type names - in this case, for copies, to invoke copy
  35. * constructors.
  36. *
  37. * When the caller wants to pass a copy of an lvalue, the caller may:
  38. *
  39. * void foo() {
  40. * MyData data;
  41. * something(folly::copy(data)); // explicit copy
  42. * something(std::move(data)); // explicit move
  43. * something(data); // const& - neither move nor copy
  44. * }
  45. *
  46. * Note: If passed an rvalue, invokes the move-ctor, not the copy-ctor. This
  47. * can be used to to force a move, where just using std::move would not:
  48. *
  49. * std::copy(std::move(data)); // force-move, not just a cast to &&
  50. *
  51. * Note: The following text appears in the standard:
  52. *
  53. * > In several places in this Clause the operation //DECAY_COPY(x)// is used.
  54. * > All such uses mean call the function `decay_copy(x)` and use the result,
  55. * > where `decay_copy` is defined as follows:
  56. * >
  57. * > template <class T> decay_t<T> decay_copy(T&& v)
  58. * > { return std::forward<T>(v); }
  59. * >
  60. * > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
  61. * > 30.2.6 `decay_copy` [thread.decaycopy].
  62. *
  63. * We mimic it, with a `noexcept` specifier for good measure.
  64. */
  65. template <typename T>
  66. constexpr typename std::decay<T>::type copy(T&& value) noexcept(
  67. noexcept(typename std::decay<T>::type(std::forward<T>(value)))) {
  68. return std::forward<T>(value);
  69. }
  70. /**
  71. * A simple helper for getting a constant reference to an object.
  72. *
  73. * Example:
  74. *
  75. * std::vector<int> v{1,2,3};
  76. * // The following two lines are equivalent:
  77. * auto a = const_cast<const std::vector<int>&>(v).begin();
  78. * auto b = folly::as_const(v).begin();
  79. *
  80. * Like C++17's std::as_const. See http://wg21.link/p0007
  81. */
  82. #if __cpp_lib_as_const || _MSC_VER
  83. /* using override */ using std::as_const;
  84. #else
  85. template <class T>
  86. constexpr T const& as_const(T& t) noexcept {
  87. return t;
  88. }
  89. template <class T>
  90. void as_const(T const&&) = delete;
  91. #endif
  92. // mimic: forward_like, p0847r0
  93. template <typename Src, typename Dst>
  94. constexpr like_t<Src, Dst>&& forward_like(Dst&& dst) noexcept {
  95. return static_cast<like_t<Src, Dst>&&>(std::forward<Dst>(dst));
  96. }
  97. #if __cpp_lib_exchange_function || _LIBCPP_STD_VER > 11 || _MSC_VER
  98. /* using override */ using std::exchange;
  99. #else
  100. // mimic: std::exchange, C++14
  101. // from: http://en.cppreference.com/w/cpp/utility/exchange, CC-BY-SA
  102. template <class T, class U = T>
  103. T exchange(T& obj, U&& new_value) {
  104. T old_value = std::move(obj);
  105. obj = std::forward<U>(new_value);
  106. return old_value;
  107. }
  108. #endif
  109. namespace utility_detail {
  110. template <typename...>
  111. struct make_seq_cat;
  112. template <
  113. template <typename T, T...> class S,
  114. typename T,
  115. T... Ta,
  116. T... Tb,
  117. T... Tc>
  118. struct make_seq_cat<S<T, Ta...>, S<T, Tb...>, S<T, Tc...>> {
  119. using type =
  120. S<T,
  121. Ta...,
  122. (sizeof...(Ta) + Tb)...,
  123. (sizeof...(Ta) + sizeof...(Tb) + Tc)...>;
  124. };
  125. // Not parameterizing by `template <typename T, T...> class, typename` because
  126. // clang precisely v4.0 fails to compile that. Note that clang v3.9 and v5.0
  127. // handle that code correctly.
  128. //
  129. // For this to work, `S0` is required to be `Sequence<T>` and `S1` is required
  130. // to be `Sequence<T, 0>`.
  131. template <std::size_t Size>
  132. struct make_seq {
  133. template <typename S0, typename S1>
  134. using apply = typename make_seq_cat<
  135. typename make_seq<Size / 2>::template apply<S0, S1>,
  136. typename make_seq<Size / 2>::template apply<S0, S1>,
  137. typename make_seq<Size % 2>::template apply<S0, S1>>::type;
  138. };
  139. template <>
  140. struct make_seq<1> {
  141. template <typename S0, typename S1>
  142. using apply = S1;
  143. };
  144. template <>
  145. struct make_seq<0> {
  146. template <typename S0, typename S1>
  147. using apply = S0;
  148. };
  149. } // namespace utility_detail
  150. #if __cpp_lib_integer_sequence || _MSC_VER
  151. /* using override */ using std::index_sequence;
  152. /* using override */ using std::integer_sequence;
  153. #else
  154. // TODO: Remove after upgrading to C++14 baseline
  155. template <class T, T... Ints>
  156. struct integer_sequence {
  157. using value_type = T;
  158. static constexpr std::size_t size() noexcept {
  159. return sizeof...(Ints);
  160. }
  161. };
  162. template <std::size_t... Ints>
  163. using index_sequence = integer_sequence<std::size_t, Ints...>;
  164. #endif
  165. #if FOLLY_HAS_BUILTIN(__make_integer_seq) || _MSC_FULL_VER >= 190023918
  166. template <typename T, std::size_t Size>
  167. using make_integer_sequence = __make_integer_seq<integer_sequence, T, Size>;
  168. #else
  169. template <typename T, std::size_t Size>
  170. using make_integer_sequence = typename utility_detail::make_seq<
  171. Size>::template apply<integer_sequence<T>, integer_sequence<T, 0>>;
  172. #endif
  173. template <std::size_t Size>
  174. using make_index_sequence = make_integer_sequence<std::size_t, Size>;
  175. template <class... T>
  176. using index_sequence_for = make_index_sequence<sizeof...(T)>;
  177. /**
  178. * Backports from C++17 of:
  179. * std::in_place_t
  180. * std::in_place_type_t
  181. * std::in_place_index_t
  182. * std::in_place
  183. * std::in_place_type
  184. * std::in_place_index
  185. */
  186. struct in_place_tag {};
  187. template <class>
  188. struct in_place_type_tag {};
  189. template <std::size_t>
  190. struct in_place_index_tag {};
  191. using in_place_t = in_place_tag (&)(in_place_tag);
  192. template <class T>
  193. using in_place_type_t = in_place_type_tag<T> (&)(in_place_type_tag<T>);
  194. template <std::size_t I>
  195. using in_place_index_t = in_place_index_tag<I> (&)(in_place_index_tag<I>);
  196. inline in_place_tag in_place(in_place_tag = {}) {
  197. return {};
  198. }
  199. template <class T>
  200. inline in_place_type_tag<T> in_place_type(in_place_type_tag<T> = {}) {
  201. return {};
  202. }
  203. template <std::size_t I>
  204. inline in_place_index_tag<I> in_place_index(in_place_index_tag<I> = {}) {
  205. return {};
  206. }
  207. /**
  208. * Initializer lists are a powerful compile time syntax introduced in C++11
  209. * but due to their often conflicting syntax they are not used by APIs for
  210. * construction.
  211. *
  212. * Further standard conforming compilers *strongly* favor an
  213. * std::initalizer_list overload for construction if one exists. The
  214. * following is a simple tag used to disambiguate construction with
  215. * initializer lists and regular uniform initialization.
  216. *
  217. * For example consider the following case
  218. *
  219. * class Something {
  220. * public:
  221. * explicit Something(int);
  222. * Something(std::intiializer_list<int>);
  223. *
  224. * operator int();
  225. * };
  226. *
  227. * ...
  228. * Something something{1}; // SURPRISE!!
  229. *
  230. * The last call to instantiate the Something object will go to the
  231. * initializer_list overload. Which may be surprising to users.
  232. *
  233. * If however this tag was used to disambiguate such construction it would be
  234. * easy for users to see which construction overload their code was referring
  235. * to. For example
  236. *
  237. * class Something {
  238. * public:
  239. * explicit Something(int);
  240. * Something(folly::initlist_construct_t, std::initializer_list<int>);
  241. *
  242. * operator int();
  243. * };
  244. *
  245. * ...
  246. * Something something_one{1}; // not the initializer_list overload
  247. * Something something_two{folly::initlist_construct, {1}}; // correct
  248. */
  249. struct initlist_construct_t {};
  250. constexpr initlist_construct_t initlist_construct{};
  251. /**
  252. * A generic tag type to indicate that some constructor or method accepts a
  253. * presorted container.
  254. *
  255. * Example:
  256. *
  257. * void takes_numbers(std::vector<int> alist) {
  258. * std::sort(alist.begin(), alist.end());
  259. * takes_numbers(folly::presorted, alist);
  260. * }
  261. *
  262. * void takes_numbers(folly::presorted_t, std::vector<int> alist) {
  263. * assert(std::is_sorted(alist.begin(), alist.end())); // debug mode only
  264. * for (i : alist) {
  265. * // some behavior which is defined and safe only when alist is sorted ...
  266. * }
  267. * }
  268. */
  269. struct presorted_t {};
  270. constexpr presorted_t presorted{};
  271. /**
  272. * A generic tag type to indicate that some constructor or method accepts an
  273. * unsorted container. Useful in contexts which might have some reason to assume
  274. * a container to be sorted.
  275. *
  276. * Example:
  277. *
  278. * void takes_numbers(std::vector<int> alist) {
  279. * takes_numbers(folly::unsorted, alist);
  280. * }
  281. *
  282. * void takes_numbers(folly::unsorted_t, std::vector<int> alist) {
  283. * std::sort(alist.begin(), alist.end());
  284. * for (i : alist) {
  285. * // some behavior which is defined and safe only when alist is sorted ...
  286. * }
  287. * }
  288. */
  289. struct unsorted_t {};
  290. constexpr unsorted_t unsorted{};
  291. template <typename T>
  292. struct transparent : T {
  293. using is_transparent = void;
  294. using T::T;
  295. };
  296. /**
  297. * A simple function object that passes its argument through unchanged.
  298. *
  299. * Example:
  300. *
  301. * int i = 42;
  302. * int &j = Identity()(i);
  303. * assert(&i == &j);
  304. *
  305. * Warning: passing a prvalue through Identity turns it into an xvalue,
  306. * which can effect whether lifetime extension occurs or not. For instance:
  307. *
  308. * auto&& x = std::make_unique<int>(42);
  309. * cout << *x ; // OK, x refers to a valid unique_ptr.
  310. *
  311. * auto&& y = Identity()(std::make_unique<int>(42));
  312. * cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It
  313. * // is no longer valid
  314. */
  315. struct Identity {
  316. template <class T>
  317. constexpr T&& operator()(T&& x) const noexcept {
  318. return static_cast<T&&>(x);
  319. }
  320. };
  321. namespace moveonly_ { // Protection from unintended ADL.
  322. /**
  323. * Disallow copy but not move in derived types. This is essentially
  324. * boost::noncopyable (the implementation is almost identical) but it
  325. * doesn't delete move constructor and move assignment.
  326. */
  327. class MoveOnly {
  328. protected:
  329. constexpr MoveOnly() = default;
  330. ~MoveOnly() = default;
  331. MoveOnly(MoveOnly&&) = default;
  332. MoveOnly& operator=(MoveOnly&&) = default;
  333. MoveOnly(const MoveOnly&) = delete;
  334. MoveOnly& operator=(const MoveOnly&) = delete;
  335. };
  336. } // namespace moveonly_
  337. using MoveOnly = moveonly_::MoveOnly;
  338. template <typename T>
  339. constexpr auto to_signed(T const& t) -> typename std::make_signed<T>::type {
  340. using S = typename std::make_signed<T>::type;
  341. // note: static_cast<S>(t) would be more straightforward, but it would also be
  342. // implementation-defined behavior and that is typically to be avoided; the
  343. // following code optimized into the same thing, though
  344. return std::numeric_limits<S>::max() < t ? -static_cast<S>(~t) + S{-1}
  345. : static_cast<S>(t);
  346. }
  347. template <typename T>
  348. constexpr auto to_unsigned(T const& t) -> typename std::make_unsigned<T>::type {
  349. using U = typename std::make_unsigned<T>::type;
  350. return static_cast<U>(t);
  351. }
  352. } // namespace folly