ICU4X
International Components for Unicode
Loading...
Searching...
No Matches
diplomat_runtime.hpp
Go to the documentation of this file.
1#ifndef DIPLOMAT_RUNTIME_CPP_H
2#define DIPLOMAT_RUNTIME_CPP_H
3
4#include <string>
5#include <variant>
6#include <array>
7#include <optional>
8#include <type_traits>
9
10#if __cplusplus >= 202002L
11#include<span>
12#endif
13
14#include "diplomat_runtime.h"
15
16namespace diplomat {
17
18extern "C" inline void Flush(capi::DiplomatWriteable* w) {
19 std::string* string = reinterpret_cast<std::string*>(w->context);
20 string->resize(w->len);
21};
22
23extern "C" inline bool Grow(capi::DiplomatWriteable* w, uintptr_t requested) {
24 std::string* string = reinterpret_cast<std::string*>(w->context);
25 string->resize(requested);
26 w->cap = string->length();
27 w->buf = &(*string)[0];
28 return true;
29};
30
31inline capi::DiplomatWriteable WriteableFromString(std::string& string) {
32 capi::DiplomatWriteable w;
33 w.context = &string;
34 w.buf = &string[0];
35 w.len = string.length();
36 // Same as length, since C++ strings are not supposed
37 // to be written to past their len; you resize *first*
38 w.cap = string.length();
39 w.flush = Flush;
40 w.grow = Grow;
41 return w;
42};
43
44template<typename T> struct WriteableTrait {
45 // static inline capi::DiplomatWriteable Construct(T& t);
46};
47
48
49template<> struct WriteableTrait<std::string> {
50 static inline capi::DiplomatWriteable Construct(std::string& t) {
52 }
53};
54
55template<class T> struct Ok {
57 Ok(T&& i): inner(std::move(i)) {}
58 // We don't want to expose an lvalue-capable constructor in general
59 // however there is no problem doing this for trivially copyable types
60 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
61 Ok(T i): inner(i) {}
62 Ok() = default;
63 Ok(Ok&&) noexcept = default;
64 Ok(const Ok &) = default;
65 Ok& operator=(const Ok&) = default;
66 Ok& operator=(Ok&&) noexcept = default;
67};
68
69template<class T> struct Err {
71 Err(T&& i): inner(std::move(i)) {}
72 // We don't want to expose an lvalue-capable constructor in general
73 // however there is no problem doing this for trivially copyable types
74 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
75 Err(T i): inner(i) {}
76 Err() = default;
77 Err(Err&&) noexcept = default;
78 Err(const Err &) = default;
79 Err& operator=(const Err&) = default;
80 Err& operator=(Err&&) noexcept = default;
81};
82
83template<class T, class E>
84class result {
85private:
86 std::variant<Ok<T>, Err<E>> val;
87public:
88 result(Ok<T>&& v): val(std::move(v)) {}
89 result(Err<E>&& v): val(std::move(v)) {}
90 result() = default;
91 result(const result &) = default;
92 result& operator=(const result&) = default;
93 result& operator=(result&&) noexcept = default;
94 result(result &&) noexcept = default;
95 ~result() = default;
96 bool is_ok() const {
97 return std::holds_alternative<Ok<T>>(this->val);
98 };
99 bool is_err() const {
100 return std::holds_alternative<Err<E>>(this->val);
101 };
102
103 std::optional<T> ok() && {
104 if (!this->is_ok()) {
105 return std::nullopt;
106 }
107 return std::make_optional(std::move(std::get<Ok<T>>(std::move(this->val)).inner));
108 };
109 std::optional<E> err() && {
110 if (!this->is_err()) {
111 return std::nullopt;
112 }
113 return std::make_optional(std::move(std::get<Err<E>>(std::move(this->val)).inner));
114 }
115
116 void set_ok(T&& t) {
117 this->val = Ok<T>(std::move(t));
118 }
119
120 void set_err(E&& e) {
121 this->val = Err<E>(std::move(e));
122 }
123
124 template<typename T2>
126 if (this->is_err()) {
127 return result<T2, E>(Err<E>(std::get<Err<E>>(std::move(this->val))));
128 } else {
129 return result<T2, E>(Ok<T2>(std::move(t)));
130 }
131 }
132};
133
134
135// Use custom std::span on C++17, otherwise use std::span
136#if __cplusplus >= 202002L
137
138template<class T> using span = std::span<T>;
139
140#else // __cplusplus >= 202002L
141
142// C++-17-compatible std::span
143template<class T>
144class span {
145
146public:
147 constexpr span(T* data, size_t size)
148 : data_(data), size_(size) {}
149 template<size_t N>
150 constexpr span(std::array<typename std::remove_const<T>::type, N>& arr)
151 : data_(const_cast<T*>(arr.data())), size_(N) {}
152 constexpr T* data() const noexcept {
153 return this->data_;
154 }
155 constexpr size_t size() const noexcept {
156 return this->size_;
157 }
158private:
159 T* data_;
160 size_t size_;
161};
162
163#endif // __cplusplus >= 202002L
164
165}
166
167#endif
result(Err< E > &&v)
Definition diplomat_runtime.hpp:89
result(const result &)=default
result & operator=(const result &)=default
result & operator=(result &&) noexcept=default
bool is_err() const
Definition diplomat_runtime.hpp:99
result(Ok< T > &&v)
Definition diplomat_runtime.hpp:88
std::optional< T > ok() &&
Definition diplomat_runtime.hpp:103
std::optional< E > err() &&
Definition diplomat_runtime.hpp:109
void set_ok(T &&t)
Definition diplomat_runtime.hpp:116
bool is_ok() const
Definition diplomat_runtime.hpp:96
result< T2, E > replace_ok(T2 &&t)
Definition diplomat_runtime.hpp:125
result()=default
void set_err(E &&e)
Definition diplomat_runtime.hpp:120
constexpr T * data() const noexcept
Definition diplomat_runtime.hpp:152
constexpr size_t size() const noexcept
Definition diplomat_runtime.hpp:155
constexpr span(std::array< typename std::remove_const< T >::type, N > &arr)
Definition diplomat_runtime.hpp:150
constexpr span(T *data, size_t size)
Definition diplomat_runtime.hpp:147
Definition diplomat_runtime.hpp:16
void Flush(capi::DiplomatWriteable *w)
Definition diplomat_runtime.hpp:18
bool Grow(capi::DiplomatWriteable *w, uintptr_t requested)
Definition diplomat_runtime.hpp:23
capi::DiplomatWriteable WriteableFromString(std::string &string)
Definition diplomat_runtime.hpp:31
Definition diplomat_runtime.hpp:69
Err(T i)
Definition diplomat_runtime.hpp:75
T inner
Definition diplomat_runtime.hpp:70
Err(T &&i)
Definition diplomat_runtime.hpp:71
Err(Err &&) noexcept=default
Err()=default
Definition diplomat_runtime.hpp:55
Ok(T i)
Definition diplomat_runtime.hpp:61
Ok(T &&i)
Definition diplomat_runtime.hpp:57
T inner
Definition diplomat_runtime.hpp:56
Ok()=default
Ok(Ok &&) noexcept=default