MySQL  8.0.26
Source Code Documentation
template_utils.h
Go to the documentation of this file.
1 /* Copyright (c) 2013, 2021, Oracle and/or its affiliates.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef TEMPLATE_UTILS_INCLUDED
24 #define TEMPLATE_UTILS_INCLUDED
25 
26 #include <assert.h>
27 #include <ctype.h>
28 #include <stddef.h>
29 #include <algorithm>
30 #include <iterator>
31 #include <type_traits>
32 
33 /**
34  @file include/template_utils.h
35 */
36 
37 /**
38  Clears a container, but deletes all objects that the elements point to first.
39  @tparam Container_type Container of pointers.
40  */
41 template <typename Container_type>
42 void delete_container_pointers(Container_type &container) {
43  typename Container_type::iterator it1 = container.begin();
44  typename Container_type::iterator it2 = container.end();
45  for (; it1 != it2; ++it1) {
46  delete (*it1);
47  }
48  container.clear();
49 }
50 
51 /**
52  Clears a container, but frees all objects that the elements point to first.
53  @tparam Container_type Container of pointers.
54  */
55 template <typename Container_type>
56 void my_free_container_pointers(Container_type &container) {
57  typename Container_type::iterator it1 = container.begin();
58  typename Container_type::iterator it2 = container.end();
59  for (; it1 != it2; ++it1) {
60  my_free(*it1);
61  }
62  container.clear();
63 }
64 
65 /**
66  Casts from one pointer type, to another, without using
67  reinterpret_cast or C-style cast:
68  foo *f; bar *b= pointer_cast<bar*>(f);
69  This avoids having to do:
70  foo *f; bar *b= static_cast<bar*>(static_cast<void*>(f));
71  */
72 template <typename T>
73 inline T pointer_cast(void *p) {
74  return static_cast<T>(p);
75 }
76 
77 template <typename T>
78 inline const T pointer_cast(const void *p) {
79  return static_cast<T>(p);
80 }
81 
82 /**
83  Casts from one pointer type to another in a type hierarchy.
84  In debug mode, we verify the cast is indeed legal.
85 
86  @tparam Target The descendent type, must be a pointer type.
87  @tparam Source The parent type.
88 
89  @param arg The pointer to be down-cast.
90 
91  @return A pointer of type Target.
92 */
93 template <typename Target, typename Source>
94 inline Target down_cast(Source *arg) {
95  static_assert(
96  !std::is_base_of<typename std::remove_pointer<Target>::type,
97  Source>::value,
98  "Do not use down_cast for upcasts; use implicit_cast or nothing");
99  assert(nullptr != dynamic_cast<Target>(arg));
100  return static_cast<Target>(arg);
101 }
102 
103 /**
104  Casts from one reference type to another in a type hierarchy.
105  In debug mode, we verify the cast is indeed legal.
106 
107  @tparam Target The descendent type, must be a reference type.
108  @tparam Source The parent type.
109 
110  @param arg The reference to be down-cast.
111 
112  @return A reference of type Target.
113 */
114 template <typename Target, typename Source>
115 inline Target down_cast(Source &arg) {
116  // We still use the pointer version of dynamic_cast, as the
117  // reference-accepting version throws exceptions, and we don't want to deal
118  // with that.
119  static_assert(
120  !std::is_base_of<typename std::remove_reference<Target>::type,
121  Source>::value,
122  "Do not use down_cast for upcasts; use implicit_cast or nothing");
123  assert(dynamic_cast<typename std::remove_reference<Target>::type *>(&arg) !=
124  nullptr);
125  return static_cast<Target>(arg);
126 }
127 
128 /**
129  Sometimes the compiler insists that types be the same and does not do any
130  implicit conversion. For example:
131  Derived1 *a;
132  Derived2 *b; // Derived1 and 2 are children classes of Base
133  Base *x= cond ? a : b; // Error, need to force a cast.
134 
135  Use:
136  Base *x= cond ? implicit_cast<Base*>(a) : implicit_cast<Base*>(b);
137  static_cast would work too, but would be less safe (allows any
138  pointer-to-pointer conversion, not only up-casts).
139 */
140 template <typename To>
141 inline To implicit_cast(To x) {
142  return x;
143 }
144 
145 /**
146  Utility to allow returning values from functions which can fail
147  (until we have std::optional).
148  */
149 template <class VALUE_TYPE>
151  /** Value returned from function in the normal case. */
152  VALUE_TYPE value;
153 
154  /** True if an error occured. */
155  bool error;
156 };
157 
158 /**
159  Number of elements in a constant C array.
160  */
161 template <class T, size_t N>
162 constexpr size_t array_elements(T (&)[N]) noexcept {
163  return N;
164 }
165 
166 namespace myu {
167 /**
168  Split a range into sub ranges delimited by elements satisfying a predicate.
169  Examines the elements from first to last, exclusive. Each time an element
170  which satisfies the splitting predicate is encountered, the action argument's
171  operator() is invoked with the starting and past-the-end iterators for the
172  current sub-range, even if this is empty. When iteration is complete, action()
173  is called on the range between the start of the last subrange and last.
174 
175  It must be possible to pass a single element with type const
176  InputIt::value_type to is_split_element. It must be possible to pass two
177  InputIt arguments to action.
178 
179  @param first Beginning of the range to split.
180  @param last End of the range to split.
181  @param pred Callable which will be invoked on each element in
182  turn to determine if it is a splitting element.
183  @param action Callable which will be invoked with the beginning
184  and one-past-the-end iterators for each subrange.
185  */
186 template <class InputIt, class Pred, class Action>
187 inline void Split(InputIt first, InputIt last, Pred &&pred, Action &&action) {
188  while (first != last) {
189  InputIt split = std::find_if(first, last, std::forward<Pred>(pred));
190  action(first, split); // Called even for empty subranges, action must
191  // discard if not wanted
192  if (split == last) return;
193  first = split + 1;
194  }
195 }
196 
197 /**
198  Search backwards for the first occurence of an element which does not satisfy
199  the trimming predicate, and return an InputIt to the element after it.
200 
201  @param first Beginning of the range to search.
202  @param last End of the range to search.
203  @param pred Callable which can be applied to a dereferenced InputIt and which
204  returns true if the element should be trimmed.
205 
206  @returns InputIt referencing the first element of sub range satisfying the
207  trimming predicate at the end of the range. last if no elements
208  satisfy the trimming predicate.
209  */
210 template <class InputIt, class Pred>
211 inline InputIt FindTrimmedEnd(InputIt first, InputIt last, Pred &&pred) {
212  return std::find_if_not(std::make_reverse_iterator(last),
213  std::make_reverse_iterator(first),
214  std::forward<Pred>(pred))
215  .base();
216 }
217 
218 /**
219  Searches for a sub range such that no elements before or after fail to
220  satisfy the trimming predicate.
221 
222  @param first Beginning of the range to search.
223  @param last End of the range to search.
224  @param pred Callable which can be applied to a dereferenced InputIt and which
225  returns true if the element should be trimmed.
226 
227  @returns Pair of iterators denoting the sub range which does not include the
228  leading and trailing sub ranges matching the trimming predicate.
229  {last, last} if all elements match the trimming predicate.
230  */
231 template <class InputIt, class Pred>
232 inline std::pair<InputIt, InputIt> FindTrimmedRange(InputIt first, InputIt last,
233  Pred &&pred) {
234  InputIt f = std::find_if_not(first, last, std::forward<Pred>(pred));
235  return {f, FindTrimmedEnd(f, last, std::forward<Pred>(pred))};
236 }
237 
238 /** Convenience lambdas for common predicates. */
239 const auto IsSpace = [](char c) { return isspace(c); };
240 const auto IsComma = [](char c) { return c == ','; };
241 
242 } // namespace myu
243 #endif // TEMPLATE_UTILS_INCLUDED
const char * p
Definition: ctype-mb.cc:1236
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:80
std::atomic< Type > N
Definition: ut0counter.h:224
Definition: atomics_array.h:38
Definition: template_utils.h:166
std::pair< InputIt, InputIt > FindTrimmedRange(InputIt first, InputIt last, Pred &&pred)
Searches for a sub range such that no elements before or after fail to satisfy the trimming predicate...
Definition: template_utils.h:232
const auto IsSpace
Convenience lambdas for common predicates.
Definition: template_utils.h:239
void Split(InputIt first, InputIt last, Pred &&pred, Action &&action)
Split a range into sub ranges delimited by elements satisfying a predicate.
Definition: template_utils.h:187
InputIt FindTrimmedEnd(InputIt first, InputIt last, Pred &&pred)
Search backwards for the first occurence of an element which does not satisfy the trimming predicate,...
Definition: template_utils.h:211
const auto IsComma
Definition: template_utils.h:240
Source
Type of memory allocated.
Definition: memutils.h:67
const string value("\"Value\"")
message Action
Definition: replication_group_member_actions.proto:29
required string type
Definition: replication_group_member_actions.proto:33
repeated Action action
Definition: replication_group_member_actions.proto:42
Utility to allow returning values from functions which can fail (until we have std::optional).
Definition: template_utils.h:150
VALUE_TYPE value
Value returned from function in the normal case.
Definition: template_utils.h:152
bool error
True if an error occured.
Definition: template_utils.h:155
To implicit_cast(To x)
Sometimes the compiler insists that types be the same and does not do any implicit conversion.
Definition: template_utils.h:141
Target down_cast(Source *arg)
Casts from one pointer type to another in a type hierarchy.
Definition: template_utils.h:94
constexpr size_t array_elements(T(&)[N]) noexcept
Number of elements in a constant C array.
Definition: template_utils.h:162
void delete_container_pointers(Container_type &container)
Clears a container, but deletes all objects that the elements point to first.
Definition: template_utils.h:42
T pointer_cast(void *p)
Casts from one pointer type, to another, without using reinterpret_cast or C-style cast: foo f; bar *...
Definition: template_utils.h:73
void my_free_container_pointers(Container_type &container)
Clears a container, but frees all objects that the elements point to first.
Definition: template_utils.h:56