1 /* Copyright (c) 2015, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #ifndef OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H 16 #define OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H 17 18 #include <assert.h> 19 20 #include <vector> 21 22 23 // This header contains re-implementations of library functions from C++11. They 24 // will be replaced with their standard counterparts once Chromium has C++11 25 // library support in its toolchain. 26 27 namespace bssl { 28 29 // vector_data is a reimplementation of |std::vector::data| from C++11. 30 template <class T> 31 static T *vector_data(std::vector<T> *out) { 32 return out->empty() ? nullptr : &(*out)[0]; 33 } 34 35 template <class T> 36 static const T *vector_data(const std::vector<T> *out) { 37 return out->empty() ? nullptr : &(*out)[0]; 38 } 39 40 // remove_reference is a reimplementation of |std::remove_reference| from C++11. 41 template <class T> 42 struct remove_reference { 43 using type = T; 44 }; 45 46 template <class T> 47 struct remove_reference<T&> { 48 using type = T; 49 }; 50 51 template <class T> 52 struct remove_reference<T&&> { 53 using type = T; 54 }; 55 56 // move is a reimplementation of |std::move| from C++11. 57 template <class T> 58 typename remove_reference<T>::type &&move(T &&t) { 59 return static_cast<typename remove_reference<T>::type&&>(t); 60 } 61 62 // default_delete is a partial reimplementation of |std::default_delete| from 63 // C++11. 64 template <class T> 65 struct default_delete { 66 void operator()(T *t) const { 67 enum { type_must_be_complete = sizeof(T) }; 68 delete t; 69 } 70 }; 71 72 // nullptr_t is |std::nullptr_t| from C++11. 73 using nullptr_t = decltype(nullptr); 74 75 // unique_ptr is a partial reimplementation of |std::unique_ptr| from C++11. It 76 // intentionally does not support stateful deleters to avoid having to bother 77 // with the empty member optimization. 78 template <class T, class Deleter = default_delete<T>> 79 class unique_ptr { 80 public: 81 unique_ptr() : ptr_(nullptr) {} 82 unique_ptr(nullptr_t) : ptr_(nullptr) {} 83 unique_ptr(T *ptr) : ptr_(ptr) {} 84 unique_ptr(const unique_ptr &u) = delete; 85 86 unique_ptr(unique_ptr &&u) : ptr_(nullptr) { 87 reset(u.release()); 88 } 89 90 ~unique_ptr() { 91 reset(); 92 } 93 94 unique_ptr &operator=(nullptr_t) { 95 reset(); 96 return *this; 97 } 98 99 unique_ptr &operator=(unique_ptr &&u) { 100 reset(u.release()); 101 return *this; 102 } 103 104 unique_ptr& operator=(const unique_ptr &u) = delete; 105 106 explicit operator bool() const { 107 return ptr_ != nullptr; 108 } 109 110 T &operator*() const { 111 assert(ptr_ != nullptr); 112 return *ptr_; 113 } 114 115 T *operator->() const { 116 assert(ptr_ != nullptr); 117 return ptr_; 118 } 119 120 T *get() const { 121 return ptr_; 122 } 123 124 T *release() { 125 T *ptr = ptr_; 126 ptr_ = nullptr; 127 return ptr; 128 } 129 130 void reset(T *ptr = nullptr) { 131 if (ptr_ != nullptr) { 132 Deleter()(ptr_); 133 } 134 ptr_ = ptr; 135 } 136 137 private: 138 T *ptr_; 139 }; 140 141 } // namespace bssl 142 143 144 #endif // OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H 145