1
+ // Copyright 2020-2024 PragmaTwice
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef PROTOPUF_CODER_MODE_H
16
+ #define PROTOPUF_CODER_MODE_H
17
+
18
+ #include < optional>
19
+ #include " byte.h"
20
+
21
+ namespace pp {
22
+
23
+ // / @brief Describes a type with static member function `make_result`,
24
+ // / which make an encoding/decoding result which depends on the coding mode.
25
+ // / @param v some object that could potentially be contained as a result of encoding.
26
+ // / @returns the encoding/decoding result which depends on the coding mode.
27
+ template <typename T>
28
+ concept coder_result_maker = requires (std::pair<int , int > v) {
29
+ typename T::template result_type<decltype (v)>;
30
+
31
+ { T::template make_result<typename T::template result_type<decltype (v)>>(0 , 0 ) } ->
32
+ std::same_as<typename T::template result_type<decltype (v)>>;
33
+ };
34
+
35
+ // / @brief Describes a type with static member function `get_value_from_result`,
36
+ // / which extract value from encoding/decoding result depending on encoding/decoding mode.
37
+ // / @param v some object that could potentially be extracted from the encoding result.
38
+ // / @param r the encoding/decoding result.
39
+ // / @returns true if the value is extracted, otherwise false.
40
+ template <typename T>
41
+ concept coder_result_value_getter = requires (std::pair<int , int > v, typename T::template result_type<decltype (v)> r) {
42
+ typename T::template result_type<decltype (v)>;
43
+
44
+ { T::template get_value_from_result<typename T::template result_type<decltype (v)>>(std::move (r), v) } -> std::same_as<bool >;
45
+ };
46
+
47
+ // / @brief Describes a type with static member function `check_iterator`,
48
+ // / which checks if an iterator is valid depending on the encoding/decoding mode.
49
+ // / @param itr the iterator that checks for validity.
50
+ // / @param end the iterator to the element following the last element.
51
+ // / @returns true if the iterator is valid, otherwise false.
52
+ template <typename T>
53
+ concept iterator_checker = requires (bytes::iterator itr, bytes::iterator end) {
54
+ { T::check_iterator (itr, end) } -> std::same_as<bool >;
55
+ };
56
+
57
+ // / @brief Describes a type with static member function `check_bytes_span`,
58
+ // / which checks if the span offset is valid depending on the encoding/decoding mode.
59
+ // / @param b the byte span.
60
+ // / @param offset offset into the span of byte that checks for validity.
61
+ // / @returns true if the offset is valid, otherwise false.
62
+ template <typename T>
63
+ concept bytes_span_checker = requires (bytes b, std::size_t offset) {
64
+ { T::check_bytes_span (b, offset) } -> std::same_as<bool >;
65
+ };
66
+
67
+ // / @brief Describes a type for the coder operating mode.
68
+ template <typename T>
69
+ concept coder_mode = coder_result_maker<T> && coder_result_value_getter<T> && iterator_checker<T> && bytes_span_checker<T>;
70
+
71
+ // / @brief Unsafe @ref coder_mode to perform coding without buffer overflow checking
72
+ struct unsafe_mode {
73
+ template <typename T>
74
+ using result_type = std::remove_reference_t <T>;
75
+
76
+ template <typename R, typename ... Args>
77
+ static constexpr R make_result (Args&&... args) {
78
+ return R{std::forward<Args>(args)...};
79
+ }
80
+
81
+ template <typename T>
82
+ static constexpr bool get_value_from_result (T&& result, auto & value) {
83
+ value = std::forward<T>(result);
84
+ return true ;
85
+ }
86
+
87
+ static constexpr bool check_iterator (bytes::iterator, bytes::iterator) {
88
+ return true ;
89
+ }
90
+
91
+ static constexpr bool check_bytes_span (bytes, std::size_t ) {
92
+ return true ;
93
+ }
94
+ };
95
+
96
+ // / @brief Safe @ref coder_mode to perform coding with buffer overflow checking (the coding result is wrapped into std::optional)
97
+ struct safe_mode {
98
+ template <typename T>
99
+ using result_type = std::optional<std::remove_reference_t <T>>;
100
+
101
+ template <typename R, typename ... Args>
102
+ static constexpr R make_result (Args&&... args) {
103
+ return R{std::in_place, std::forward<Args>(args)...};
104
+ }
105
+
106
+ template <typename T>
107
+ static constexpr bool get_value_from_result (T&& result, auto & value) {
108
+ if (result.has_value ()) {
109
+ value = std::forward<decltype (*result)>(*result);
110
+ } else {
111
+ return false ;
112
+ }
113
+ return true ;
114
+ }
115
+
116
+ static constexpr bool check_iterator (bytes::iterator iter, bytes::iterator end) {
117
+ return iter != end;
118
+ }
119
+
120
+ static constexpr bool check_bytes_span (bytes b, std::size_t offset) {
121
+ return b.size () >= offset;
122
+ }
123
+ };
124
+
125
+ }
126
+
127
+ #endif // PROTOPUF_CODER_MODE_H
0 commit comments