Mangrove
The C++ Object Document Mapper for MongoDB
util.hpp
1 // Copyright 2016 MongoDB Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <mangrove/config/prelude.hpp>
18 
19 #include <chrono>
20 #include <ctime>
21 #include <string>
22 #include <tuple>
23 #include <type_traits>
24 #include <utility>
25 
26 #include <bsoncxx/stdx/optional.hpp>
27 #include <bsoncxx/types.hpp>
28 
29 namespace mangrove {
30 MANGROVE_INLINE_NAMESPACE_BEGIN
31 
32 template <bool...>
33 struct bool_pack;
34 
39 template <bool... bs>
40 struct all_true : public std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>> {};
41 
45 template <typename S>
46 struct is_string
47  : std::integral_constant<
48  bool, std::is_same<char *, typename std::decay<S>::type>::value ||
49  std::is_same<const char *, typename std::decay<S>::type>::value ||
50  std::is_same<wchar_t *, typename std::decay<S>::type>::value ||
51  std::is_same<const wchar_t *, typename std::decay<S>::type>::value> {};
52 
53 template <typename Char, typename Traits, typename Allocator>
54 struct is_string<std::basic_string<Char, Traits, Allocator>> : std::true_type {};
55 
56 template <typename S>
57 constexpr bool is_string_v = is_string<S>::value;
58 
64 // To allow ADL with custom begin/end
65 using std::begin;
66 using std::end;
67 
68 template <typename T>
69 auto is_iterable_impl(int)
70  -> decltype(begin(std::declval<T &>()) !=
71  end(std::declval<T &>()), // begin/end and operator !=
72  void(), // Handle evil operator ,
73  ++std::declval<decltype(begin(std::declval<T &>())) &>(), // operator ++
74  void(*begin(std::declval<T &>())), // operator*
75  std::true_type{});
76 
77 template <typename>
78 std::false_type is_iterable_impl(...);
79 
80 template <typename T>
81 using is_iterable = decltype(is_iterable_impl<T>(0));
82 
83 template <typename T>
84 constexpr bool is_iterable_v = is_iterable<T>::value;
85 
86 // Matches iterables, but NOT strings or char arrays.
87 template <typename T>
88 using is_iterable_not_string = std::integral_constant<int, is_iterable_v<T> && !is_string_v<T>>;
89 
90 template <typename T>
91 constexpr bool is_iterable_not_string_v = is_iterable_not_string<T>::value;
92 
98 template <typename T>
99 typename T::iterator::value_type iterable_value_impl(int);
100 
101 template <typename T>
102 T iterable_value_impl(...);
103 
104 template <typename T>
105 using iterable_value_t = decltype(iterable_value_impl<T>(0));
106 
110 template <typename T>
111 struct is_optional : public std::false_type {};
112 
113 template <typename T>
114 struct is_optional<bsoncxx::stdx::optional<T>> : public std::true_type {};
115 
116 template <typename T>
117 constexpr bool is_optional_v = is_optional<T>::value;
118 
123 template <typename T>
125  using type = T;
126 };
127 
128 template <typename T>
129 struct remove_optional<bsoncxx::stdx::optional<T>> {
130  using type = T;
131 };
132 
133 template <typename T>
134 using remove_optional_t = typename remove_optional<T>::type;
135 
136 constexpr std::int64_t bit_positions_to_mask() {
137  return 0;
138 }
139 
140 template <typename... Args>
141 constexpr std::int64_t bit_positions_to_mask(std::int64_t pos, Args... positions) {
142  pos<0 || pos> 63 ? throw std::logic_error("Invalid pos") : 0;
143  return (1 << pos) | bit_positions_to_mask(positions...);
144 }
145 
152 template <typename T>
153 struct is_date : public std::false_type {};
154 
155 template <typename Rep, typename Period>
156 struct is_date<std::chrono::duration<Rep, Period>> : public std::true_type {};
157 
158 template <typename Clock, typename Duration>
159 struct is_date<std::chrono::time_point<Clock, Duration>> : public std::true_type {};
160 
161 template <>
162 struct is_date<bsoncxx::types::b_date> : public std::true_type {};
163 
164 template <typename T>
165 constexpr bool is_date_v = is_date<T>::value;
166 
170 template <typename Map, typename... Ts, size_t... idxs>
171 constexpr void tuple_for_each_impl(const std::tuple<Ts...> &tup, Map &&map,
172  std::index_sequence<idxs...>) {
173  (void)std::initializer_list<int>{(map(std::get<idxs>(tup)), 0)...};
174 }
175 
176 template <typename Map, typename... Ts>
177 constexpr void tuple_for_each(const std::tuple<Ts...> &tup, Map &&map) {
178  return tuple_for_each_impl(tup, std::forward<Map>(map), std::index_sequence_for<Ts...>());
179 }
180 
186 template <typename... Ts>
187 struct first_two_types_are_same : public std::false_type {};
188 
189 template <typename T, typename T2, typename... Ts>
190 struct first_two_types_are_same<T, T2, Ts...> : public std::is_same<T, std::decay_t<T2>> {};
191 
198 template <typename container_type, typename T>
199 struct container_of : public std::is_same<typename container_type::value_type, T> {};
200 
201 template <typename container_type, typename T>
202 constexpr bool container_of_v = container_of<container_type, T>::value;
203 
210 template <typename iterator_type, typename T>
212  : public std::is_same<typename std::iterator_traits<iterator_type>::value_type, T> {};
213 
214 template <typename iterator_type, typename T>
215 constexpr bool iterator_of_v = iterator_of<iterator_type, T>::value;
216 
217 MANGROVE_INLINE_NAMESPACE_END
218 } // namespace mangrove
219 
220 #include <mangrove/config/postlude.hpp>
Type trait that checks whether or not an iterator iterates a particular type.
Definition: util.hpp:211
A templated struct that contains its templated type, but with optionals unwrapped.
Definition: util.hpp:124
A type trait struct for determining whether a type is a string or C string.
Definition: util.hpp:46
A type trait struct for determining whether a type is an optional.
Definition: util.hpp:111
Definition: util.hpp:33
A type traits struct that determines whether a certain type stores a date.
Definition: util.hpp:153
Definition: collection_wrapper.hpp:28
A templated struct for determining whether a variadic list of boolean conditions is all true...
Definition: util.hpp:40
Type trait that checks whether or not a type is a container that contains a particular type...
Definition: util.hpp:199
Helper type trait widget that helps properly forward arguments to _id constructor in mangrove::model...
Definition: util.hpp:187