1 #ifndef EAGINE_SSL_API_OBJECT_STACK_HPP
9 #define EAGINE_SSL_API_OBJECT_STACK_HPP
11 #include "../assert.hpp"
15 namespace eagine::sslp {
17 template <
typename Handle>
20 template <
typename Tag>
21 class object_stack<basic_handle<Tag, nothing_t*,
nullptr>> {
23 constexpr
auto size() const noexcept ->
int {
27 constexpr
auto push(basic_handle<Tag, nothing_t*, nullptr>) ->
auto& {
31 constexpr
auto pop() ->
auto& {
35 constexpr
auto get(
int) -> basic_handle<Tag, nothing_t*, nullptr> {
39 constexpr
auto native() const noexcept -> nothing_t* {
46 template <
typename Tag>
50 struct stack_api<x509_tag> {
51 using stack_type = STACK_OF(X509);
52 using element_type = ::X509;
54 static auto unpack(x509 obj) noexcept ->
auto* {
55 return static_cast<::X509*
>(obj);
58 static auto new_null() noexcept -> auto* {
59 return sk_X509_new_null();
62 static auto free(stack_type* h) noexcept {
63 return sk_X509_free(h);
66 static auto num(stack_type* h) noexcept {
67 return sk_X509_num(h);
70 static auto push(stack_type* h, element_type* e) noexcept {
71 return sk_X509_push(h, e);
74 static auto push_up_ref(stack_type* h, element_type* e) noexcept {
76 return sk_X509_push(h, e);
79 static auto pop(stack_type* h) noexcept ->
auto* {
80 return sk_X509_pop(h);
83 static auto pop_free(stack_type* h) noexcept {
84 return sk_X509_pop_free(h, &X509_free);
87 static auto set(stack_type* h,
int i, element_type* e) noexcept {
88 return sk_X509_set(h, i, e);
91 static auto value(stack_type* h,
int i) noexcept ->
auto* {
92 return sk_X509_value(h, i);
98 template <
typename Handle>
99 class object_stack_base;
101 template <
typename Tag,
typename T>
102 class object_stack_base<basic_handle<Tag, T*,
nullptr>> : stack_api<Tag> {
104 typename stack_api<Tag>::stack_type* _top{
nullptr};
106 auto _api() const noexcept -> const stack_api<Tag>& {
110 object_stack_base(
typename stack_api<Tag>::stack_type* top) noexcept
113 auto _idx_ok(
int i)
const noexcept ->
bool {
114 return (i >= 0) && (i < size());
117 ~object_stack_base() noexcept = default;
120 using wrapper = basic_handle<Tag, T*,
nullptr>;
122 object_stack_base(object_stack_base&& temp) noexcept
127 object_stack_base(
const object_stack_base&) =
delete;
129 auto operator=(object_stack_base&& temp) noexcept -> object_stack_base& {
131 swap(_top, temp._top);
135 auto operator=(
const object_stack_base&) =
delete;
137 auto size() const noexcept ->
int {
138 return _api().num(_top);
142 EAGINE_ASSERT(_idx_ok(pos));
143 return wrapper{_api().value(_top, pos)};
146 auto native() const noexcept -> auto* {
153 template <
typename Tag,
typename T>
154 class object_stack<basic_handle<Tag, T*,
nullptr>>
155 : object_stack_base<basic_handle<Tag, T*, nullptr>> {
157 using base = object_stack_base<basic_handle<Tag, T*, nullptr>>;
162 using wrapper = basic_handle<Tag, T*, nullptr>;
164 object_stack() noexcept
165 : base{_api().new_null()} {}
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;
172 ~object_stack() noexcept {
173 _api.free()(this->_top);
176 auto push(wrapper obj) ->
auto& {
177 _api().push(this->_top, _api().unpack(obj));
182 return wrapper{_api().pop(this->_top)};
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>> {
192 using base = object_stack_base<basic_handle<Tag, T*, nullptr>>;
197 using wrapper = basic_owned_handle<Tag, T*, nullptr>;
199 object_stack() noexcept
200 : base{_api().new_null()} {}
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;
207 ~object_stack() noexcept {
208 _api.pop_free()(this->_top);
211 auto push(wrapper&& obj) ->
auto& {
212 _api().push_up_ref(this->_top, _api().unpack(obj.release()));
217 return wrapper{_api().pop(this->_top)};
224 #endif // EAGINE_SSL_API_OBJECT_STACK_HPP