OGLplus  (0.59.0) a C++ wrapper for rendering APIs

object_stack.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_SSL_API_OBJECT_STACK_HPP
9 #define EAGINE_SSL_API_OBJECT_STACK_HPP
10 
11 #include "../assert.hpp"
12 #include "object_handle.hpp"
13 #include <utility>
14 
15 namespace eagine::sslp {
16 //------------------------------------------------------------------------------
17 template <typename Handle>
18 class object_stack;
19 //------------------------------------------------------------------------------
20 template <typename Tag>
21 class object_stack<basic_handle<Tag, nothing_t*, nullptr>> {
22 public:
23  constexpr auto size() const noexcept -> int {
24  return 0;
25  }
26 
27  constexpr auto push(basic_handle<Tag, nothing_t*, nullptr>) -> auto& {
28  return *this;
29  }
30 
31  constexpr auto pop() -> auto& {
32  return *this;
33  }
34 
35  constexpr auto get(int) -> basic_handle<Tag, nothing_t*, nullptr> {
36  return {};
37  }
38 
39  constexpr auto native() const noexcept -> nothing_t* {
40  return nullptr;
41  }
42 };
43 //------------------------------------------------------------------------------
44 #if EAGINE_HAS_SSL
45 //------------------------------------------------------------------------------
46 template <typename Tag>
47 struct stack_api;
48 //------------------------------------------------------------------------------
49 template <>
50 struct stack_api<x509_tag> {
51  using stack_type = STACK_OF(X509);
52  using element_type = ::X509;
53 
54  static auto unpack(x509 obj) noexcept -> auto* {
55  return static_cast<::X509*>(obj);
56  }
57 
58  static auto new_null() noexcept -> auto* {
59  return sk_X509_new_null();
60  }
61 
62  static auto free(stack_type* h) noexcept {
63  return sk_X509_free(h);
64  }
65 
66  static auto num(stack_type* h) noexcept {
67  return sk_X509_num(h);
68  }
69 
70  static auto push(stack_type* h, element_type* e) noexcept {
71  return sk_X509_push(h, e);
72  }
73 
74  static auto push_up_ref(stack_type* h, element_type* e) noexcept {
75  X509_up_ref(e);
76  return sk_X509_push(h, e);
77  }
78 
79  static auto pop(stack_type* h) noexcept -> auto* {
80  return sk_X509_pop(h);
81  }
82 
83  static auto pop_free(stack_type* h) noexcept {
84  return sk_X509_pop_free(h, &X509_free);
85  }
86 
87  static auto set(stack_type* h, int i, element_type* e) noexcept {
88  return sk_X509_set(h, i, e);
89  }
90 
91  static auto value(stack_type* h, int i) noexcept -> auto* {
92  return sk_X509_value(h, i);
93  }
94 };
95 //------------------------------------------------------------------------------
96 // object_stack_base
97 //------------------------------------------------------------------------------
98 template <typename Handle>
99 class object_stack_base;
100 
101 template <typename Tag, typename T>
102 class object_stack_base<basic_handle<Tag, T*, nullptr>> : stack_api<Tag> {
103 protected:
104  typename stack_api<Tag>::stack_type* _top{nullptr};
105 
106  auto _api() const noexcept -> const stack_api<Tag>& {
107  return *this;
108  }
109 
110  object_stack_base(typename stack_api<Tag>::stack_type* top) noexcept
111  : _top{top} {}
112 
113  auto _idx_ok(int i) const noexcept -> bool {
114  return (i >= 0) && (i < size());
115  }
116 
117  ~object_stack_base() noexcept = default;
118 
119 public:
120  using wrapper = basic_handle<Tag, T*, nullptr>;
121 
122  object_stack_base(object_stack_base&& temp) noexcept
123  : _top{temp._top} {
124  temp._top = nullptr;
125  }
126 
127  object_stack_base(const object_stack_base&) = delete;
128 
129  auto operator=(object_stack_base&& temp) noexcept -> object_stack_base& {
130  using std::swap;
131  swap(_top, temp._top);
132  return *this;
133  }
134 
135  auto operator=(const object_stack_base&) = delete;
136 
137  auto size() const noexcept -> int {
138  return _api().num(_top);
139  }
140 
141  auto get(int pos) {
142  EAGINE_ASSERT(_idx_ok(pos));
143  return wrapper{_api().value(_top, pos)};
144  }
145 
146  auto native() const noexcept -> auto* {
147  return _top;
148  }
149 };
150 //------------------------------------------------------------------------------
151 // object_stack
152 //------------------------------------------------------------------------------
153 template <typename Tag, typename T>
154 class object_stack<basic_handle<Tag, T*, nullptr>>
155  : object_stack_base<basic_handle<Tag, T*, nullptr>> {
156 
157  using base = object_stack_base<basic_handle<Tag, T*, nullptr>>;
158  using base::_api;
159  using base::_idx_ok;
160 
161 public:
162  using wrapper = basic_handle<Tag, T*, nullptr>;
163 
164  object_stack() noexcept
165  : base{_api().new_null()} {}
166 
167  object_stack(object_stack&&) noexcept = delete;
168  object_stack(const object_stack&) = delete;
169  auto operator=(object_stack&&) noexcept -> object_stack& = default;
170  auto operator=(const object_stack&) = delete;
171 
172  ~object_stack() noexcept {
173  _api.free()(this->_top);
174  }
175 
176  auto push(wrapper obj) -> auto& {
177  _api().push(this->_top, _api().unpack(obj));
178  return *this;
179  }
180 
181  auto pop() {
182  return wrapper{_api().pop(this->_top)};
183  }
184 };
185 //------------------------------------------------------------------------------
186 // object_stack owned
187 //------------------------------------------------------------------------------
188 template <typename Tag, typename T>
189 class object_stack<basic_owned_handle<Tag, T*, nullptr>>
190  : object_stack_base<basic_handle<Tag, T*, nullptr>> {
191 
192  using base = object_stack_base<basic_handle<Tag, T*, nullptr>>;
193  using base::_api;
194  using base::_idx_ok;
195 
196 public:
197  using wrapper = basic_owned_handle<Tag, T*, nullptr>;
198 
199  object_stack() noexcept
200  : base{_api().new_null()} {}
201 
202  object_stack(object_stack&&) noexcept = delete;
203  object_stack(const object_stack&) = delete;
204  auto operator=(object_stack&&) noexcept -> object_stack& = default;
205  auto operator=(const object_stack&) = delete;
206 
207  ~object_stack() noexcept {
208  _api.pop_free()(this->_top);
209  }
210 
211  auto push(wrapper&& obj) -> auto& {
212  _api().push_up_ref(this->_top, _api().unpack(obj.release()));
213  return *this;
214  }
215 
216  auto pop() {
217  return wrapper{_api().pop(this->_top)};
218  }
219 };
220 #endif
221 //------------------------------------------------------------------------------
222 } // namespace eagine::sslp
223 
224 #endif // EAGINE_SSL_API_OBJECT_STACK_HPP

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).