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