• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <string>
21 #include <type_traits>
22 #include <vector>
23 #include <memory>
24 #include <limits>
25 
26 #if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
27   #define FLATBUFFERS_CPP98_STL
28 #endif  // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
29 
30 #if defined(FLATBUFFERS_CPP98_STL)
31   #include <cctype>
32 #endif  // defined(FLATBUFFERS_CPP98_STL)
33 
34 // This header provides backwards compatibility for C++98 STLs like stlport.
35 namespace flatbuffers {
36 
37 // Retrieve ::back() from a string in a way that is compatible with pre C++11
38 // STLs (e.g stlport).
string_back(const std::string & value)39 inline char string_back(const std::string &value) {
40   return value[value.length() - 1];
41 }
42 
43 // Helper method that retrieves ::data() from a vector in a way that is
44 // compatible with pre C++11 STLs (e.g stlport).
vector_data(std::vector<T> & vector)45 template <typename T> inline T *vector_data(std::vector<T> &vector) {
46   // In some debug environments, operator[] does bounds checking, so &vector[0]
47   // can't be used.
48   return &(*vector.begin());
49 }
50 
vector_data(const std::vector<T> & vector)51 template <typename T> inline const T *vector_data(
52     const std::vector<T> &vector) {
53   return &(*vector.begin());
54 }
55 
56 template <typename T, typename V>
vector_emplace_back(std::vector<T> * vector,V && data)57 inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
58   #if defined(FLATBUFFERS_CPP98_STL)
59     vector->push_back(data);
60   #else
61     vector->emplace_back(std::forward<V>(data));
62   #endif  // defined(FLATBUFFERS_CPP98_STL)
63 }
64 
65 #ifndef FLATBUFFERS_CPP98_STL
66   #if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
67     template <typename T>
68     using numeric_limits = std::numeric_limits<T>;
69   #else
70     template <typename T> class numeric_limits :
71       public std::numeric_limits<T> {};
72   #endif  // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
73 #else
74   template <typename T> class numeric_limits :
75       public std::numeric_limits<T> {};
76 
77   template <> class numeric_limits<unsigned long long> {
78    public:
min()79     static unsigned long long min() { return 0ULL; }
max()80     static unsigned long long max() { return ~0ULL; }
81   };
82 
83   template <> class numeric_limits<long long> {
84    public:
min()85     static long long min() {
86       return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
87     }
max()88     static long long max() {
89       return static_cast<long long>(
90           (1ULL << ((sizeof(long long) << 3) - 1)) - 1);
91     }
92   };
93 #endif  // FLATBUFFERS_CPP98_STL
94 
95 #if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
96   #ifndef FLATBUFFERS_CPP98_STL
97     template <typename T> using is_scalar = std::is_scalar<T>;
98     template <typename T, typename U> using is_same = std::is_same<T,U>;
99     template <typename T> using is_floating_point = std::is_floating_point<T>;
100     template <typename T> using is_unsigned = std::is_unsigned<T>;
101   #else
102     // Map C++ TR1 templates defined by stlport.
103     template <typename T> using is_scalar = std::tr1::is_scalar<T>;
104     template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
105     template <typename T> using is_floating_point =
106         std::tr1::is_floating_point<T>;
107     template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
108   #endif  // !FLATBUFFERS_CPP98_STL
109 #else
110   // MSVC 2010 doesn't support C++11 aliases.
111   template <typename T> struct is_scalar : public std::is_scalar<T> {};
112   template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
113   template <typename T> struct is_floating_point :
114         public std::is_floating_point<T> {};
115   template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
116 #endif  // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
117 
118 #ifndef FLATBUFFERS_CPP98_STL
119   #if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
120     template <class T> using unique_ptr = std::unique_ptr<T>;
121   #else
122     // MSVC 2010 doesn't support C++11 aliases.
123     // We're manually "aliasing" the class here as we want to bring unique_ptr
124     // into the flatbuffers namespace.  We have unique_ptr in the flatbuffers
125     // namespace we have a completely independent implemenation (see below)
126     // for C++98 STL implementations.
127     template <class T> class unique_ptr : public std::unique_ptr<T> {
128      public:
unique_ptr()129       unique_ptr() {}
unique_ptr(T * p)130       explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
unique_ptr(std::unique_ptr<T> && u)131       unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
unique_ptr(unique_ptr && u)132       unique_ptr(unique_ptr&& u) { *this = std::move(u); }
133       unique_ptr& operator=(std::unique_ptr<T>&& u) {
134         std::unique_ptr<T>::reset(u.release());
135         return *this;
136       }
137       unique_ptr& operator=(unique_ptr&& u) {
138         std::unique_ptr<T>::reset(u.release());
139         return *this;
140       }
141       unique_ptr& operator=(T* p) {
142         return std::unique_ptr<T>::operator=(p);
143       }
144     };
145   #endif  // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
146 #else
147   // Very limited implementation of unique_ptr.
148   // This is provided simply to allow the C++ code generated from the default
149   // settings to function in C++98 environments with no modifications.
150   template <class T> class unique_ptr {
151    public:
152     typedef T element_type;
153 
unique_ptr()154     unique_ptr() : ptr_(nullptr) {}
unique_ptr(T * p)155     explicit unique_ptr(T* p) : ptr_(p) {}
unique_ptr(unique_ptr && u)156     unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
unique_ptr(const unique_ptr & u)157     unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
158       reset(const_cast<unique_ptr*>(&u)->release());
159     }
~unique_ptr()160     ~unique_ptr() { reset(); }
161 
162     unique_ptr& operator=(const unique_ptr& u) {
163       reset(const_cast<unique_ptr*>(&u)->release());
164       return *this;
165     }
166 
167     unique_ptr& operator=(unique_ptr&& u) {
168       reset(u.release());
169       return *this;
170     }
171 
172     unique_ptr& operator=(T* p) {
173       reset(p);
174       return *this;
175     }
176 
177     const T& operator*() const { return *ptr_; }
178     T* operator->() const { return ptr_; }
get()179     T* get() const noexcept { return ptr_; }
180     explicit operator bool() const { return ptr_ != nullptr; }
181 
182     // modifiers
release()183     T* release() {
184       T* value = ptr_;
185       ptr_ = nullptr;
186       return value;
187     }
188 
189     void reset(T* p = nullptr) {
190       T* value = ptr_;
191       ptr_ = p;
192       if (value) delete value;
193     }
194 
swap(unique_ptr & u)195     void swap(unique_ptr& u) {
196       T* temp_ptr = ptr_;
197       ptr_ = u.ptr_;
198       u.ptr_ = temp_ptr;
199     }
200 
201    private:
202     T* ptr_;
203   };
204 
205   template <class T> bool operator==(const unique_ptr<T>& x,
206                                      const unique_ptr<T>& y) {
207     return x.get() == y.get();
208   }
209 
210   template <class T, class D> bool operator==(const unique_ptr<T>& x,
211                                               const D* y) {
212     return static_cast<D*>(x.get()) == y;
213   }
214 
215   template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
216     return reinterpret_cast<intptr_t>(x.get()) == y;
217   }
218 #endif  // !FLATBUFFERS_CPP98_STL
219 
220 }  // namespace flatbuffers
221 
222 #endif  // FLATBUFFERS_STL_EMULATION_H_
223