Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef FLATBUFFERS_STL_EMULATION_H_
00018 #define FLATBUFFERS_STL_EMULATION_H_
00019
00020
00021
00022 #include <string>
00023 #include <type_traits>
00024 #include <vector>
00025 #include <memory>
00026 #include <limits>
00027
00028 #if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
00029 #define FLATBUFFERS_CPP98_STL
00030 #endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
00031
00032 #if defined(FLATBUFFERS_CPP98_STL)
00033 #include <cctype>
00034 #endif // defined(FLATBUFFERS_CPP98_STL)
00035
00036
00037
00038
00039
00040 #if (defined(_MSC_VER) && _MSC_VER > 1700 ) \
00041 || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \
00042 || (defined(__cplusplus) && __cplusplus >= 201103L)
00043 #define FLATBUFFERS_TEMPLATES_ALIASES
00044 #endif
00045
00046
00047 namespace flatbuffers {
00048
00049
00050
00051 inline char& string_back(std::string &value) {
00052 return value[value.length() - 1];
00053 }
00054
00055 inline char string_back(const std::string &value) {
00056 return value[value.length() - 1];
00057 }
00058
00059
00060
00061 template <typename T> inline T *vector_data(std::vector<T> &vector) {
00062
00063
00064 return vector.empty() ? nullptr : &vector[0];
00065 }
00066
00067 template <typename T> inline const T *vector_data(
00068 const std::vector<T> &vector) {
00069 return vector.empty() ? nullptr : &vector[0];
00070 }
00071
00072 template <typename T, typename V>
00073 inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
00074 #if defined(FLATBUFFERS_CPP98_STL)
00075 vector->push_back(data);
00076 #else
00077 vector->emplace_back(std::forward<V>(data));
00078 #endif // defined(FLATBUFFERS_CPP98_STL)
00079 }
00080
00081 #ifndef FLATBUFFERS_CPP98_STL
00082 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
00083 template <typename T>
00084 using numeric_limits = std::numeric_limits<T>;
00085 #else
00086 template <typename T> class numeric_limits :
00087 public std::numeric_limits<T> {};
00088 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
00089 #else
00090 template <typename T> class numeric_limits :
00091 public std::numeric_limits<T> {
00092 public:
00093
00094 static T lowest() {
00095 return std::numeric_limits<T>::min();
00096 }
00097 };
00098
00099 template <> class numeric_limits<float> :
00100 public std::numeric_limits<float> {
00101 public:
00102 static float lowest() { return -FLT_MAX; }
00103 };
00104
00105 template <> class numeric_limits<double> :
00106 public std::numeric_limits<double> {
00107 public:
00108 static double lowest() { return -DBL_MAX; }
00109 };
00110
00111 template <> class numeric_limits<unsigned long long> {
00112 public:
00113 static unsigned long long min() { return 0ULL; }
00114 static unsigned long long max() { return ~0ULL; }
00115 static unsigned long long lowest() {
00116 return numeric_limits<unsigned long long>::min();
00117 }
00118 };
00119
00120 template <> class numeric_limits<long long> {
00121 public:
00122 static long long min() {
00123 return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
00124 }
00125 static long long max() {
00126 return static_cast<long long>(
00127 (1ULL << ((sizeof(long long) << 3) - 1)) - 1);
00128 }
00129 static long long lowest() {
00130 return numeric_limits<long long>::min();
00131 }
00132 };
00133 #endif // FLATBUFFERS_CPP98_STL
00134
00135 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
00136 #ifndef FLATBUFFERS_CPP98_STL
00137 template <typename T> using is_scalar = std::is_scalar<T>;
00138 template <typename T, typename U> using is_same = std::is_same<T,U>;
00139 template <typename T> using is_floating_point = std::is_floating_point<T>;
00140 template <typename T> using is_unsigned = std::is_unsigned<T>;
00141 template <typename T> using make_unsigned = std::make_unsigned<T>;
00142 #else
00143
00144 template <typename T> using is_scalar = std::tr1::is_scalar<T>;
00145 template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
00146 template <typename T> using is_floating_point =
00147 std::tr1::is_floating_point<T>;
00148 template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
00149
00150 template<typename T> struct make_unsigned {
00151 static_assert(is_unsigned<T>::value, "Specialization not implemented!");
00152 using type = T;
00153 };
00154 template<> struct make_unsigned<char> { using type = unsigned char; };
00155 template<> struct make_unsigned<short> { using type = unsigned short; };
00156 template<> struct make_unsigned<int> { using type = unsigned int; };
00157 template<> struct make_unsigned<long> { using type = unsigned long; };
00158 template<>
00159 struct make_unsigned<long long> { using type = unsigned long long; };
00160 #endif // !FLATBUFFERS_CPP98_STL
00161 #else
00162
00163 template <typename T> struct is_scalar : public std::is_scalar<T> {};
00164 template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
00165 template <typename T> struct is_floating_point :
00166 public std::is_floating_point<T> {};
00167 template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
00168 template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
00169 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
00170
00171 #ifndef FLATBUFFERS_CPP98_STL
00172 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
00173 template <class T> using unique_ptr = std::unique_ptr<T>;
00174 #else
00175
00176
00177
00178
00179
00180 template <class T> class unique_ptr : public std::unique_ptr<T> {
00181 public:
00182 unique_ptr() {}
00183 explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
00184 unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
00185 unique_ptr(unique_ptr&& u) { *this = std::move(u); }
00186 unique_ptr& operator=(std::unique_ptr<T>&& u) {
00187 std::unique_ptr<T>::reset(u.release());
00188 return *this;
00189 }
00190 unique_ptr& operator=(unique_ptr&& u) {
00191 std::unique_ptr<T>::reset(u.release());
00192 return *this;
00193 }
00194 unique_ptr& operator=(T* p) {
00195 return std::unique_ptr<T>::operator=(p);
00196 }
00197 };
00198 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
00199 #else
00200
00201
00202
00203 template <class T> class unique_ptr {
00204 public:
00205 typedef T element_type;
00206
00207 unique_ptr() : ptr_(nullptr) {}
00208 explicit unique_ptr(T* p) : ptr_(p) {}
00209 unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
00210 unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
00211 reset(const_cast<unique_ptr*>(&u)->release());
00212 }
00213 ~unique_ptr() { reset(); }
00214
00215 unique_ptr& operator=(const unique_ptr& u) {
00216 reset(const_cast<unique_ptr*>(&u)->release());
00217 return *this;
00218 }
00219
00220 unique_ptr& operator=(unique_ptr&& u) {
00221 reset(u.release());
00222 return *this;
00223 }
00224
00225 unique_ptr& operator=(T* p) {
00226 reset(p);
00227 return *this;
00228 }
00229
00230 const T& operator*() const { return *ptr_; }
00231 T* operator->() const { return ptr_; }
00232 T* get() const noexcept { return ptr_; }
00233 explicit operator bool() const { return ptr_ != nullptr; }
00234
00235
00236 T* release() {
00237 T* value = ptr_;
00238 ptr_ = nullptr;
00239 return value;
00240 }
00241
00242 void reset(T* p = nullptr) {
00243 T* value = ptr_;
00244 ptr_ = p;
00245 if (value) delete value;
00246 }
00247
00248 void swap(unique_ptr& u) {
00249 T* temp_ptr = ptr_;
00250 ptr_ = u.ptr_;
00251 u.ptr_ = temp_ptr;
00252 }
00253
00254 private:
00255 T* ptr_;
00256 };
00257
00258 template <class T> bool operator==(const unique_ptr<T>& x,
00259 const unique_ptr<T>& y) {
00260 return x.get() == y.get();
00261 }
00262
00263 template <class T, class D> bool operator==(const unique_ptr<T>& x,
00264 const D* y) {
00265 return static_cast<D*>(x.get()) == y;
00266 }
00267
00268 template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
00269 return reinterpret_cast<intptr_t>(x.get()) == y;
00270 }
00271 #endif // !FLATBUFFERS_CPP98_STL
00272
00273 }
00274
00275 #endif // FLATBUFFERS_STL_EMULATION_H_