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>
vector_data(std::vector<T> * out)31 static T *vector_data(std::vector<T> *out) {
32 return out->empty() ? nullptr : &(*out)[0];
33 }
34
35 template <class T>
vector_data(const std::vector<T> * out)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