1a8923222033763f1a74f836c656af19d9f620378Stewart Miles/* 2a8923222033763f1a74f836c656af19d9f620378Stewart Miles * Copyright 2017 Google Inc. All rights reserved. 3a8923222033763f1a74f836c656af19d9f620378Stewart Miles * 4a8923222033763f1a74f836c656af19d9f620378Stewart Miles * Licensed under the Apache License, Version 2.0 (the "License"); 5a8923222033763f1a74f836c656af19d9f620378Stewart Miles * you may not use this file except in compliance with the License. 6a8923222033763f1a74f836c656af19d9f620378Stewart Miles * You may obtain a copy of the License at 7a8923222033763f1a74f836c656af19d9f620378Stewart Miles * 8a8923222033763f1a74f836c656af19d9f620378Stewart Miles * http://www.apache.org/licenses/LICENSE-2.0 9a8923222033763f1a74f836c656af19d9f620378Stewart Miles * 10a8923222033763f1a74f836c656af19d9f620378Stewart Miles * Unless required by applicable law or agreed to in writing, software 11a8923222033763f1a74f836c656af19d9f620378Stewart Miles * distributed under the License is distributed on an "AS IS" BASIS, 12a8923222033763f1a74f836c656af19d9f620378Stewart Miles * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8923222033763f1a74f836c656af19d9f620378Stewart Miles * See the License for the specific language governing permissions and 14a8923222033763f1a74f836c656af19d9f620378Stewart Miles * limitations under the License. 15a8923222033763f1a74f836c656af19d9f620378Stewart Miles */ 16a8923222033763f1a74f836c656af19d9f620378Stewart Miles 17a8923222033763f1a74f836c656af19d9f620378Stewart Miles#ifndef FLATBUFFERS_STL_EMULATION_H_ 18a8923222033763f1a74f836c656af19d9f620378Stewart Miles#define FLATBUFFERS_STL_EMULATION_H_ 19a8923222033763f1a74f836c656af19d9f620378Stewart Miles 20a8923222033763f1a74f836c656af19d9f620378Stewart Miles#include <string> 21a8923222033763f1a74f836c656af19d9f620378Stewart Miles#include <type_traits> 22a8923222033763f1a74f836c656af19d9f620378Stewart Miles#include <vector> 23d233b38008f30cb671fe03f14963806ffcbf99cbWouter van Oortmerssen#include <memory> 24d233b38008f30cb671fe03f14963806ffcbf99cbWouter van Oortmerssen#include <limits> 25a8923222033763f1a74f836c656af19d9f620378Stewart Miles 26a8923222033763f1a74f836c656af19d9f620378Stewart Miles#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) 27a8923222033763f1a74f836c656af19d9f620378Stewart Miles #define FLATBUFFERS_CPP98_STL 28a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) 29a8923222033763f1a74f836c656af19d9f620378Stewart Miles 30a8923222033763f1a74f836c656af19d9f620378Stewart Miles#if defined(FLATBUFFERS_CPP98_STL) 31a8923222033763f1a74f836c656af19d9f620378Stewart Miles #include <cctype> 32a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // defined(FLATBUFFERS_CPP98_STL) 33a8923222033763f1a74f836c656af19d9f620378Stewart Miles 34a8923222033763f1a74f836c656af19d9f620378Stewart Miles// This header provides backwards compatibility for C++98 STLs like stlport. 35a8923222033763f1a74f836c656af19d9f620378Stewart Milesnamespace flatbuffers { 36a8923222033763f1a74f836c656af19d9f620378Stewart Miles 37a8923222033763f1a74f836c656af19d9f620378Stewart Miles// Retrieve ::back() from a string in a way that is compatible with pre C++11 38a8923222033763f1a74f836c656af19d9f620378Stewart Miles// STLs (e.g stlport). 39a8923222033763f1a74f836c656af19d9f620378Stewart Milesinline char string_back(const std::string &value) { 40a8923222033763f1a74f836c656af19d9f620378Stewart Miles return value[value.length() - 1]; 41a8923222033763f1a74f836c656af19d9f620378Stewart Miles} 42a8923222033763f1a74f836c656af19d9f620378Stewart Miles 43a8923222033763f1a74f836c656af19d9f620378Stewart Miles// Helper method that retrieves ::data() from a vector in a way that is 44a8923222033763f1a74f836c656af19d9f620378Stewart Miles// compatible with pre C++11 STLs (e.g stlport). 45a8923222033763f1a74f836c656af19d9f620378Stewart Milestemplate <typename T> inline T *vector_data(std::vector<T> &vector) { 4697face1527989f59479ab61d47bb13765257bf8aAlex Ames // In some debug environments, operator[] does bounds checking, so &vector[0] 4797face1527989f59479ab61d47bb13765257bf8aAlex Ames // can't be used. 4897face1527989f59479ab61d47bb13765257bf8aAlex Ames return &(*vector.begin()); 49a8923222033763f1a74f836c656af19d9f620378Stewart Miles} 50a8923222033763f1a74f836c656af19d9f620378Stewart Miles 51a8923222033763f1a74f836c656af19d9f620378Stewart Milestemplate <typename T> inline const T *vector_data( 52a8923222033763f1a74f836c656af19d9f620378Stewart Miles const std::vector<T> &vector) { 5397face1527989f59479ab61d47bb13765257bf8aAlex Ames return &(*vector.begin()); 54a8923222033763f1a74f836c656af19d9f620378Stewart Miles} 55a8923222033763f1a74f836c656af19d9f620378Stewart Miles 56a8923222033763f1a74f836c656af19d9f620378Stewart Milestemplate <typename T, typename V> 57a8923222033763f1a74f836c656af19d9f620378Stewart Milesinline void vector_emplace_back(std::vector<T> *vector, V &&data) { 58a8923222033763f1a74f836c656af19d9f620378Stewart Miles #if defined(FLATBUFFERS_CPP98_STL) 59a8923222033763f1a74f836c656af19d9f620378Stewart Miles vector->push_back(data); 60a8923222033763f1a74f836c656af19d9f620378Stewart Miles #else 61a8923222033763f1a74f836c656af19d9f620378Stewart Miles vector->emplace_back(std::forward<V>(data)); 62a8923222033763f1a74f836c656af19d9f620378Stewart Miles #endif // defined(FLATBUFFERS_CPP98_STL) 63a8923222033763f1a74f836c656af19d9f620378Stewart Miles} 64a8923222033763f1a74f836c656af19d9f620378Stewart Miles 65a8923222033763f1a74f836c656af19d9f620378Stewart Miles#ifndef FLATBUFFERS_CPP98_STL 66a8923222033763f1a74f836c656af19d9f620378Stewart Miles #if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 67a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> 68a8923222033763f1a74f836c656af19d9f620378Stewart Miles using numeric_limits = std::numeric_limits<T>; 69a8923222033763f1a74f836c656af19d9f620378Stewart Miles #else 70a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> class numeric_limits : 71a8923222033763f1a74f836c656af19d9f620378Stewart Miles public std::numeric_limits<T> {}; 72a8923222033763f1a74f836c656af19d9f620378Stewart Miles #endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 73a8923222033763f1a74f836c656af19d9f620378Stewart Miles#else 74a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> class numeric_limits : 75a8923222033763f1a74f836c656af19d9f620378Stewart Miles public std::numeric_limits<T> {}; 76a8923222033763f1a74f836c656af19d9f620378Stewart Miles 77a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <> class numeric_limits<unsigned long long> { 78a8923222033763f1a74f836c656af19d9f620378Stewart Miles public: 79a8923222033763f1a74f836c656af19d9f620378Stewart Miles static unsigned long long min() { return 0ULL; } 80a8923222033763f1a74f836c656af19d9f620378Stewart Miles static unsigned long long max() { return ~0ULL; } 81a8923222033763f1a74f836c656af19d9f620378Stewart Miles }; 82a8923222033763f1a74f836c656af19d9f620378Stewart Miles 83a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <> class numeric_limits<long long> { 84a8923222033763f1a74f836c656af19d9f620378Stewart Miles public: 85a8923222033763f1a74f836c656af19d9f620378Stewart Miles static long long min() { 86a8923222033763f1a74f836c656af19d9f620378Stewart Miles return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1)); 87a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 88a8923222033763f1a74f836c656af19d9f620378Stewart Miles static long long max() { 89a8923222033763f1a74f836c656af19d9f620378Stewart Miles return static_cast<long long>( 90a8923222033763f1a74f836c656af19d9f620378Stewart Miles (1ULL << ((sizeof(long long) << 3) - 1)) - 1); 91a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 92a8923222033763f1a74f836c656af19d9f620378Stewart Miles }; 93a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // FLATBUFFERS_CPP98_STL 94a8923222033763f1a74f836c656af19d9f620378Stewart Miles 95a8923222033763f1a74f836c656af19d9f620378Stewart Miles#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 96a8923222033763f1a74f836c656af19d9f620378Stewart Miles #ifndef FLATBUFFERS_CPP98_STL 97a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_scalar = std::is_scalar<T>; 9876744a434514297dabc38a6eee3fc5fa40db2924rouzier template <typename T, typename U> using is_same = std::is_same<T,U>; 99a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_floating_point = std::is_floating_point<T>; 100a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_unsigned = std::is_unsigned<T>; 101a8923222033763f1a74f836c656af19d9f620378Stewart Miles #else 102a8923222033763f1a74f836c656af19d9f620378Stewart Miles // Map C++ TR1 templates defined by stlport. 103a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_scalar = std::tr1::is_scalar<T>; 10476744a434514297dabc38a6eee3fc5fa40db2924rouzier template <typename T, typename U> using is_same = std::tr1::is_same<T,U>; 105a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_floating_point = 106a8923222033763f1a74f836c656af19d9f620378Stewart Miles std::tr1::is_floating_point<T>; 107a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> using is_unsigned = std::tr1::is_unsigned<T>; 108a8923222033763f1a74f836c656af19d9f620378Stewart Miles #endif // !FLATBUFFERS_CPP98_STL 109a8923222033763f1a74f836c656af19d9f620378Stewart Miles#else 110a8923222033763f1a74f836c656af19d9f620378Stewart Miles // MSVC 2010 doesn't support C++11 aliases. 111a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> struct is_scalar : public std::is_scalar<T> {}; 11276744a434514297dabc38a6eee3fc5fa40db2924rouzier template <typename T, typename U> struct is_same : public std::is_same<T,U> {}; 113a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> struct is_floating_point : 114a8923222033763f1a74f836c656af19d9f620378Stewart Miles public std::is_floating_point<T> {}; 115a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <typename T> struct is_unsigned : public std::is_unsigned<T> {}; 116a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 117a8923222033763f1a74f836c656af19d9f620378Stewart Miles 118a8923222033763f1a74f836c656af19d9f620378Stewart Miles#ifndef FLATBUFFERS_CPP98_STL 119a8923222033763f1a74f836c656af19d9f620378Stewart Miles #if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 120a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T> using unique_ptr = std::unique_ptr<T>; 121a8923222033763f1a74f836c656af19d9f620378Stewart Miles #else 122a8923222033763f1a74f836c656af19d9f620378Stewart Miles // MSVC 2010 doesn't support C++11 aliases. 123a8923222033763f1a74f836c656af19d9f620378Stewart Miles // We're manually "aliasing" the class here as we want to bring unique_ptr 124a8923222033763f1a74f836c656af19d9f620378Stewart Miles // into the flatbuffers namespace. We have unique_ptr in the flatbuffers 125a8923222033763f1a74f836c656af19d9f620378Stewart Miles // namespace we have a completely independent implemenation (see below) 126a8923222033763f1a74f836c656af19d9f620378Stewart Miles // for C++98 STL implementations. 127a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T> class unique_ptr : public std::unique_ptr<T> { 128a8923222033763f1a74f836c656af19d9f620378Stewart Miles public: 129a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr() {} 130a8923222033763f1a74f836c656af19d9f620378Stewart Miles explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {} 131a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); } 132a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr(unique_ptr&& u) { *this = std::move(u); } 133a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(std::unique_ptr<T>&& u) { 134a8923222033763f1a74f836c656af19d9f620378Stewart Miles std::unique_ptr<T>::reset(u.release()); 135a8923222033763f1a74f836c656af19d9f620378Stewart Miles return *this; 136a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 137a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(unique_ptr&& u) { 138a8923222033763f1a74f836c656af19d9f620378Stewart Miles std::unique_ptr<T>::reset(u.release()); 139a8923222033763f1a74f836c656af19d9f620378Stewart Miles return *this; 140a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 141a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(T* p) { 142a8923222033763f1a74f836c656af19d9f620378Stewart Miles return std::unique_ptr<T>::operator=(p); 143a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 144a8923222033763f1a74f836c656af19d9f620378Stewart Miles }; 145a8923222033763f1a74f836c656af19d9f620378Stewart Miles #endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */) 146a8923222033763f1a74f836c656af19d9f620378Stewart Miles#else 147a8923222033763f1a74f836c656af19d9f620378Stewart Miles // Very limited implementation of unique_ptr. 148a8923222033763f1a74f836c656af19d9f620378Stewart Miles // This is provided simply to allow the C++ code generated from the default 149a8923222033763f1a74f836c656af19d9f620378Stewart Miles // settings to function in C++98 environments with no modifications. 150a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T> class unique_ptr { 151a8923222033763f1a74f836c656af19d9f620378Stewart Miles public: 152a8923222033763f1a74f836c656af19d9f620378Stewart Miles typedef T element_type; 153a8923222033763f1a74f836c656af19d9f620378Stewart Miles 154a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr() : ptr_(nullptr) {} 155a8923222033763f1a74f836c656af19d9f620378Stewart Miles explicit unique_ptr(T* p) : ptr_(p) {} 156a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); } 157a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr(const unique_ptr& u) : ptr_(nullptr) { 158a8923222033763f1a74f836c656af19d9f620378Stewart Miles reset(const_cast<unique_ptr*>(&u)->release()); 159a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 160a8923222033763f1a74f836c656af19d9f620378Stewart Miles ~unique_ptr() { reset(); } 161a8923222033763f1a74f836c656af19d9f620378Stewart Miles 162a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(const unique_ptr& u) { 163a8923222033763f1a74f836c656af19d9f620378Stewart Miles reset(const_cast<unique_ptr*>(&u)->release()); 164a8923222033763f1a74f836c656af19d9f620378Stewart Miles return *this; 165a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 166a8923222033763f1a74f836c656af19d9f620378Stewart Miles 167a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(unique_ptr&& u) { 168a8923222033763f1a74f836c656af19d9f620378Stewart Miles reset(u.release()); 169a8923222033763f1a74f836c656af19d9f620378Stewart Miles return *this; 170a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 171a8923222033763f1a74f836c656af19d9f620378Stewart Miles 172a8923222033763f1a74f836c656af19d9f620378Stewart Miles unique_ptr& operator=(T* p) { 173a8923222033763f1a74f836c656af19d9f620378Stewart Miles reset(p); 174a8923222033763f1a74f836c656af19d9f620378Stewart Miles return *this; 175a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 176a8923222033763f1a74f836c656af19d9f620378Stewart Miles 177b0fd1a8c66a58c3749d50fe4379b4bcffcfb6514Anthony const T& operator*() const { return *ptr_; } 178a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* operator->() const { return ptr_; } 179a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* get() const noexcept { return ptr_; } 180a8923222033763f1a74f836c656af19d9f620378Stewart Miles explicit operator bool() const { return ptr_ != nullptr; } 181a8923222033763f1a74f836c656af19d9f620378Stewart Miles 182a8923222033763f1a74f836c656af19d9f620378Stewart Miles // modifiers 183a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* release() { 184a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* value = ptr_; 185a8923222033763f1a74f836c656af19d9f620378Stewart Miles ptr_ = nullptr; 186a8923222033763f1a74f836c656af19d9f620378Stewart Miles return value; 187a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 188a8923222033763f1a74f836c656af19d9f620378Stewart Miles 189a8923222033763f1a74f836c656af19d9f620378Stewart Miles void reset(T* p = nullptr) { 190a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* value = ptr_; 191a8923222033763f1a74f836c656af19d9f620378Stewart Miles ptr_ = p; 192a8923222033763f1a74f836c656af19d9f620378Stewart Miles if (value) delete value; 193a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 194a8923222033763f1a74f836c656af19d9f620378Stewart Miles 195a8923222033763f1a74f836c656af19d9f620378Stewart Miles void swap(unique_ptr& u) { 196a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* temp_ptr = ptr_; 197a8923222033763f1a74f836c656af19d9f620378Stewart Miles ptr_ = u.ptr_; 198a8923222033763f1a74f836c656af19d9f620378Stewart Miles u.ptr_ = temp_ptr; 199a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 200a8923222033763f1a74f836c656af19d9f620378Stewart Miles 201a8923222033763f1a74f836c656af19d9f620378Stewart Miles private: 202a8923222033763f1a74f836c656af19d9f620378Stewart Miles T* ptr_; 203a8923222033763f1a74f836c656af19d9f620378Stewart Miles }; 204a8923222033763f1a74f836c656af19d9f620378Stewart Miles 205a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T> bool operator==(const unique_ptr<T>& x, 206a8923222033763f1a74f836c656af19d9f620378Stewart Miles const unique_ptr<T>& y) { 207a8923222033763f1a74f836c656af19d9f620378Stewart Miles return x.get() == y.get(); 208a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 209a8923222033763f1a74f836c656af19d9f620378Stewart Miles 210a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T, class D> bool operator==(const unique_ptr<T>& x, 211a8923222033763f1a74f836c656af19d9f620378Stewart Miles const D* y) { 212a8923222033763f1a74f836c656af19d9f620378Stewart Miles return static_cast<D*>(x.get()) == y; 213a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 214a8923222033763f1a74f836c656af19d9f620378Stewart Miles 215a8923222033763f1a74f836c656af19d9f620378Stewart Miles template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) { 216a8923222033763f1a74f836c656af19d9f620378Stewart Miles return reinterpret_cast<intptr_t>(x.get()) == y; 217a8923222033763f1a74f836c656af19d9f620378Stewart Miles } 218a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // !FLATBUFFERS_CPP98_STL 219a8923222033763f1a74f836c656af19d9f620378Stewart Miles 220a8923222033763f1a74f836c656af19d9f620378Stewart Miles} // namespace flatbuffers 221a8923222033763f1a74f836c656af19d9f620378Stewart Miles 222a8923222033763f1a74f836c656af19d9f620378Stewart Miles#endif // FLATBUFFERS_STL_EMULATION_H_ 223