]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/third-party/folly/folly/Utility.h
buildsys: change download over to reef release
[ceph.git] / ceph / src / rocksdb / third-party / folly / folly / Utility.h
CommitLineData
f67539c2
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5
6#pragma once
7
8#include <utility>
9#include <type_traits>
10
11namespace folly {
12
13/**
14 * Backports from C++17 of:
15 * std::in_place_t
16 * std::in_place_type_t
17 * std::in_place_index_t
18 * std::in_place
19 * std::in_place_type
20 * std::in_place_index
21 */
22
23struct in_place_tag {};
24template <class>
25struct in_place_type_tag {};
26template <std::size_t>
27struct in_place_index_tag {};
28
29using in_place_t = in_place_tag (&)(in_place_tag);
30template <class T>
31using in_place_type_t = in_place_type_tag<T> (&)(in_place_type_tag<T>);
32template <std::size_t I>
33using in_place_index_t = in_place_index_tag<I> (&)(in_place_index_tag<I>);
34
35inline in_place_tag in_place(in_place_tag = {}) {
36 return {};
37}
38template <class T>
39inline in_place_type_tag<T> in_place_type(in_place_type_tag<T> = {}) {
40 return {};
41}
42template <std::size_t I>
43inline in_place_index_tag<I> in_place_index(in_place_index_tag<I> = {}) {
44 return {};
45}
46
47template <class T, class U = T>
48T exchange(T& obj, U&& new_value) {
49 T old_value = std::move(obj);
50 obj = std::forward<U>(new_value);
51 return old_value;
52}
53
54namespace utility_detail {
55template <typename...>
56struct make_seq_cat;
57template <
58 template <typename T, T...> class S,
59 typename T,
60 T... Ta,
61 T... Tb,
62 T... Tc>
63struct make_seq_cat<S<T, Ta...>, S<T, Tb...>, S<T, Tc...>> {
64 using type =
65 S<T,
66 Ta...,
67 (sizeof...(Ta) + Tb)...,
68 (sizeof...(Ta) + sizeof...(Tb) + Tc)...>;
69};
70
71// Not parameterizing by `template <typename T, T...> class, typename` because
72// clang precisely v4.0 fails to compile that. Note that clang v3.9 and v5.0
73// handle that code correctly.
74//
75// For this to work, `S0` is required to be `Sequence<T>` and `S1` is required
76// to be `Sequence<T, 0>`.
77
78template <std::size_t Size>
79struct make_seq {
80 template <typename S0, typename S1>
81 using apply = typename make_seq_cat<
82 typename make_seq<Size / 2>::template apply<S0, S1>,
83 typename make_seq<Size / 2>::template apply<S0, S1>,
84 typename make_seq<Size % 2>::template apply<S0, S1>>::type;
85};
86template <>
87struct make_seq<1> {
88 template <typename S0, typename S1>
89 using apply = S1;
90};
91template <>
92struct make_seq<0> {
93 template <typename S0, typename S1>
94 using apply = S0;
95};
96} // namespace utility_detail
97
98// TODO: Remove after upgrading to C++14 baseline
99
100template <class T, T... Ints>
101struct integer_sequence {
102 using value_type = T;
103
104 static constexpr std::size_t size() noexcept {
105 return sizeof...(Ints);
106 }
107};
108
109template <std::size_t... Ints>
110using index_sequence = integer_sequence<std::size_t, Ints...>;
111
112template <typename T, std::size_t Size>
113using make_integer_sequence = typename utility_detail::make_seq<
114 Size>::template apply<integer_sequence<T>, integer_sequence<T, 0>>;
115
116template <std::size_t Size>
117using make_index_sequence = make_integer_sequence<std::size_t, Size>;
118template <class... T>
119using index_sequence_for = make_index_sequence<sizeof...(T)>;
120
121/**
122 * A simple helper for getting a constant reference to an object.
123 *
124 * Example:
125 *
126 * std::vector<int> v{1,2,3};
127 * // The following two lines are equivalent:
128 * auto a = const_cast<const std::vector<int>&>(v).begin();
129 * auto b = folly::as_const(v).begin();
130 *
131 * Like C++17's std::as_const. See http://wg21.link/p0007
132 */
133template <class T>
134T const& as_const(T& t) noexcept {
135 return t;
136}
137
138template <class T>
139void as_const(T const&&) = delete;
140
141} // namespace folly