stl_emulation.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Google Inc. All rights reserved.
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 
17 #ifndef FLATBUFFERS_STL_EMULATION_H_
18 #define FLATBUFFERS_STL_EMULATION_H_
19 
20 // clang-format off
21 
22 #include <string>
23 #include <type_traits>
24 #include <vector>
25 #include <memory>
26 #include <limits>
27 
28 #if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
29  #define FLATBUFFERS_CPP98_STL
30 #endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
31 
32 #if defined(FLATBUFFERS_CPP98_STL)
33  #include <cctype>
34 #endif // defined(FLATBUFFERS_CPP98_STL)
35 
36 // Check if we can use template aliases
37 // Not possible if Microsoft Compiler before 2012
38 // Possible is the language feature __cpp_alias_templates is defined well
39 // Or possible if the C++ std is C+11 or newer
40 #if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \
41  || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \
42  || (defined(__cplusplus) && __cplusplus >= 201103L)
43  #define FLATBUFFERS_TEMPLATES_ALIASES
44 #endif
45 
46 // This header provides backwards compatibility for C++98 STLs like stlport.
47 namespace flatbuffers {
48 
49 // Retrieve ::back() from a string in a way that is compatible with pre C++11
50 // STLs (e.g stlport).
51 inline char& string_back(std::string &value) {
52  return value[value.length() - 1];
53 }
54 
55 inline char string_back(const std::string &value) {
56  return value[value.length() - 1];
57 }
58 
59 // Helper method that retrieves ::data() from a vector in a way that is
60 // compatible with pre C++11 STLs (e.g stlport).
61 template <typename T> inline T *vector_data(std::vector<T> &vector) {
62  // In some debug environments, operator[] does bounds checking, so &vector[0]
63  // can't be used.
64  return vector.empty() ? nullptr : &vector[0];
65 }
66 
67 template <typename T> inline const T *vector_data(
68  const std::vector<T> &vector) {
69  return vector.empty() ? nullptr : &vector[0];
70 }
71 
72 template <typename T, typename V>
73 inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
74  #if defined(FLATBUFFERS_CPP98_STL)
75  vector->push_back(data);
76  #else
77  vector->emplace_back(std::forward<V>(data));
78  #endif // defined(FLATBUFFERS_CPP98_STL)
79 }
80 
81 #ifndef FLATBUFFERS_CPP98_STL
82  #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
83  template <typename T>
84  using numeric_limits = std::numeric_limits<T>;
85  #else
86  template <typename T> class numeric_limits :
87  public std::numeric_limits<T> {};
88  #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
89 #else
90  template <typename T> class numeric_limits :
91  public std::numeric_limits<T> {
92  public:
93  // Android NDK fix.
94  static T lowest() {
95  return std::numeric_limits<T>::min();
96  }
97  };
98 
99  template <> class numeric_limits<float> :
100  public std::numeric_limits<float> {
101  public:
102  static float lowest() { return -FLT_MAX; }
103  };
104 
105  template <> class numeric_limits<double> :
106  public std::numeric_limits<double> {
107  public:
108  static double lowest() { return -DBL_MAX; }
109  };
110 
111  template <> class numeric_limits<unsigned long long> {
112  public:
113  static unsigned long long min() { return 0ULL; }
114  static unsigned long long max() { return ~0ULL; }
115  static unsigned long long lowest() {
117  }
118  };
119 
120  template <> class numeric_limits<long long> {
121  public:
122  static long long min() {
123  return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
124  }
125  static long long max() {
126  return static_cast<long long>(
127  (1ULL << ((sizeof(long long) << 3) - 1)) - 1);
128  }
129  static long long lowest() {
131  }
132  };
133 #endif // FLATBUFFERS_CPP98_STL
134 
135 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
136  #ifndef FLATBUFFERS_CPP98_STL
137  template <typename T> using is_scalar = std::is_scalar<T>;
138  template <typename T, typename U> using is_same = std::is_same<T,U>;
139  template <typename T> using is_floating_point = std::is_floating_point<T>;
140  template <typename T> using is_unsigned = std::is_unsigned<T>;
141  template <typename T> using make_unsigned = std::make_unsigned<T>;
142  #else
143  // Map C++ TR1 templates defined by stlport.
144  template <typename T> using is_scalar = std::tr1::is_scalar<T>;
145  template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
146  template <typename T> using is_floating_point =
147  std::tr1::is_floating_point<T>;
148  template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
149  // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
150  template<typename T> struct make_unsigned {
151  static_assert(is_unsigned<T>::value, "Specialization not implemented!");
152  using type = T;
153  };
154  template<> struct make_unsigned<char> { using type = unsigned char; };
155  template<> struct make_unsigned<short> { using type = unsigned short; };
156  template<> struct make_unsigned<int> { using type = unsigned int; };
157  template<> struct make_unsigned<long> { using type = unsigned long; };
158  template<>
159  struct make_unsigned<long long> { using type = unsigned long long; };
160  #endif // !FLATBUFFERS_CPP98_STL
161 #else
162  // MSVC 2010 doesn't support C++11 aliases.
163  template <typename T> struct is_scalar : public std::is_scalar<T> {};
164  template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
165  template <typename T> struct is_floating_point :
166  public std::is_floating_point<T> {};
167  template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
168  template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
169 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
170 
171 #ifndef FLATBUFFERS_CPP98_STL
172  #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
173  template <class T> using unique_ptr = std::unique_ptr<T>;
174  #else
175  // MSVC 2010 doesn't support C++11 aliases.
176  // We're manually "aliasing" the class here as we want to bring unique_ptr
177  // into the flatbuffers namespace. We have unique_ptr in the flatbuffers
178  // namespace we have a completely independent implemenation (see below)
179  // for C++98 STL implementations.
180  template <class T> class unique_ptr : public std::unique_ptr<T> {
181  public:
183  explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
184  unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
185  unique_ptr(unique_ptr&& u) { *this = std::move(u); }
186  unique_ptr& operator=(std::unique_ptr<T>&& u) {
187  std::unique_ptr<T>::reset(u.release());
188  return *this;
189  }
191  std::unique_ptr<T>::reset(u.release());
192  return *this;
193  }
195  return std::unique_ptr<T>::operator=(p);
196  }
197  };
198  #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
199 #else
200  // Very limited implementation of unique_ptr.
201  // This is provided simply to allow the C++ code generated from the default
202  // settings to function in C++98 environments with no modifications.
203  template <class T> class unique_ptr {
204  public:
205  typedef T element_type;
206 
207  unique_ptr() : ptr_(nullptr) {}
208  explicit unique_ptr(T* p) : ptr_(p) {}
209  unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
210  unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
211  reset(const_cast<unique_ptr*>(&u)->release());
212  }
213  ~unique_ptr() { reset(); }
214 
215  unique_ptr& operator=(const unique_ptr& u) {
216  reset(const_cast<unique_ptr*>(&u)->release());
217  return *this;
218  }
219 
220  unique_ptr& operator=(unique_ptr&& u) {
221  reset(u.release());
222  return *this;
223  }
224 
225  unique_ptr& operator=(T* p) {
226  reset(p);
227  return *this;
228  }
229 
230  const T& operator*() const { return *ptr_; }
231  T* operator->() const { return ptr_; }
232  T* get() const noexcept { return ptr_; }
233  explicit operator bool() const { return ptr_ != nullptr; }
234 
235  // modifiers
236  T* release() {
237  T* value = ptr_;
238  ptr_ = nullptr;
239  return value;
240  }
241 
242  void reset(T* p = nullptr) {
243  T* value = ptr_;
244  ptr_ = p;
245  if (value) delete value;
246  }
247 
248  void swap(unique_ptr& u) {
249  T* temp_ptr = ptr_;
250  ptr_ = u.ptr_;
251  u.ptr_ = temp_ptr;
252  }
253 
254  private:
255  T* ptr_;
256  };
257 
258  template <class T> bool operator==(const unique_ptr<T>& x,
259  const unique_ptr<T>& y) {
260  return x.get() == y.get();
261  }
262 
263  template <class T, class D> bool operator==(const unique_ptr<T>& x,
264  const D* y) {
265  return static_cast<D*>(x.get()) == y;
266  }
267 
268  template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
269  return reinterpret_cast<intptr_t>(x.get()) == y;
270  }
271 #endif // !FLATBUFFERS_CPP98_STL
272 
273 } // namespace flatbuffers
274 
275 #endif // FLATBUFFERS_STL_EMULATION_H_
unique_ptr(unique_ptr &&u)
unique_ptr(std::unique_ptr< T > &&u)
unique_ptr & operator=(unique_ptr &&u)
unique_ptr & operator=(T *p)
Definition: any.hpp:455
void swap(linb::any &lhs, linb::any &rhs) noexcept
Definition: any.hpp:457
T * vector_data(std::vector< T > &vector)
Definition: stl_emulation.h:61
const T * data(const std::vector< T, Alloc > &v)
void vector_emplace_back(std::vector< T > *vector, V &&data)
Definition: stl_emulation.h:73
unique_ptr & operator=(std::unique_ptr< T > &&u)
char & string_back(std::string &value)
Definition: stl_emulation.h:51


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 18:04:05