cpp-msgpack-light 0.3.0
A light library to serialize MessagePack.
Loading...
Searching...
No Matches
integer.h
Go to the documentation of this file.
1/*
2 * Copyright 2024 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <cstdint>
23#include <type_traits>
24
27
29
30namespace details {
31
37template <typename T>
38constexpr bool is_integer_v = std::is_integral_v<T> && !std::is_same_v<T, bool>;
39
45template <typename T>
46constexpr bool is_signed_integer_v = is_integer_v<T> && std::is_signed_v<T>;
47
53template <typename T>
54constexpr bool is_unsigned_integer_v = is_integer_v<T> && std::is_unsigned_v<T>;
55
61template <typename T>
62constexpr auto max_positive_fixint = static_cast<T>(0x7F);
63
69template <typename T>
70constexpr auto max_uint8 = static_cast<T>(0xFF);
71
77template <typename T>
78constexpr auto max_uint16 = static_cast<T>(0xFFFF);
79
85template <typename T>
86constexpr auto max_uint32 = static_cast<T>(0xFFFFFFFF);
87
93template <typename T>
94constexpr auto min_negative_fixint =
95 // NOLINTNEXTLINE: false positive
96 static_cast<T>(static_cast<std::int8_t>(0b11100000));
97
103template <typename T>
104constexpr auto min_int8 =
105 // NOLINTNEXTLINE: false positive
106 static_cast<T>(static_cast<std::int8_t>(0X80));
107
113template <typename T>
114constexpr auto min_int16 = static_cast<T>(static_cast<std::int16_t>(0X8000));
115
121template <typename T>
122constexpr auto min_int32 =
123 static_cast<T>(static_cast<std::int32_t>(0X80000000));
124
125} // namespace details
126
132template <typename T>
134 std::enable_if_t<details::is_unsigned_integer_v<T> && sizeof(T) == 1U>> {
141 static void serialize(serialization_buffer& buffer, T value) {
142 constexpr T positive_fixint_mask = ~details::max_positive_fixint<T>;
143 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
144 buffer.serialize_positive_fixint(static_cast<std::uint8_t>(value));
145 return;
146 }
147
148 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
149 }
150};
151
157template <typename T>
159 std::enable_if_t<details::is_unsigned_integer_v<T> && sizeof(T) == 2U>> {
166 static void serialize(serialization_buffer& buffer, T value) {
167 constexpr T uint8_mask = ~details::max_uint8<T>;
168 if ((value & uint8_mask) == static_cast<T>(0)) {
169 constexpr T positive_fixint_mask = ~details::max_positive_fixint<T>;
170 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
172 static_cast<std::uint8_t>(value));
173 return;
174 }
175
176 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
177 return;
178 }
179
180 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
181 }
182};
183
189template <typename T>
191 std::enable_if_t<details::is_unsigned_integer_v<T> && sizeof(T) == 4U>> {
198 static void serialize(serialization_buffer& buffer, T value) {
199 constexpr T uint8_mask = ~details::max_uint8<T>;
200 if ((value & uint8_mask) == static_cast<T>(0)) {
201 constexpr T positive_fixint_mask = ~details::max_positive_fixint<T>;
202 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
204 static_cast<std::uint8_t>(value));
205 return;
206 }
207
208 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
209 return;
210 }
211
212 constexpr T uint16_mask = ~details::max_uint16<T>;
213 if ((value & uint16_mask) == static_cast<T>(0)) {
214 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
215 return;
216 }
217
218 buffer.serialize_uint32(static_cast<std::uint32_t>(value));
219 }
220};
221
227template <typename T>
229 std::enable_if_t<details::is_unsigned_integer_v<T> &&
230 // NOLINTNEXTLINE(readability-magic-numbers)
231 sizeof(T) == 8U>> {
238 static void serialize(serialization_buffer& buffer, T value) {
239 constexpr T uint16_mask = ~details::max_uint16<T>;
240 if ((value & uint16_mask) == static_cast<T>(0)) {
241 constexpr T uint8_mask = ~details::max_uint8<T>;
242 if ((value & uint8_mask) == static_cast<T>(0)) {
243 constexpr T positive_fixint_mask =
244 ~details::max_positive_fixint<T>;
245 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
247 static_cast<std::uint8_t>(value));
248 return;
249 }
250
251 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
252 return;
253 }
254
255 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
256 return;
257 }
258
259 constexpr T uint32_mask = ~details::max_uint32<T>;
260 if ((value & uint32_mask) == static_cast<T>(0)) {
261 buffer.serialize_uint32(static_cast<std::uint32_t>(value));
262 return;
263 }
264
265 buffer.serialize_uint64(static_cast<std::uint64_t>(value));
266 }
267};
268
274template <typename T>
276 std::enable_if_t<details::is_signed_integer_v<T> && sizeof(T) == 1U>> {
277public:
284 static void serialize(serialization_buffer& buffer, T value) {
285 if (value >= static_cast<T>(0)) {
286 serialize_positive_integer(buffer, value);
287 } else {
288 serialize_negative_integer(buffer, value);
289 }
290 }
291
292private:
300 serialization_buffer& buffer, T value) {
301 buffer.serialize_positive_fixint(static_cast<std::uint8_t>(value));
302 }
303
311 serialization_buffer& buffer, T value) {
312 constexpr T negative_fixint_mask = details::min_negative_fixint<T>;
313 if ((value & negative_fixint_mask) == negative_fixint_mask) {
314 buffer.serialize_negative_fixint(static_cast<std::int8_t>(value));
315 return;
316 }
317
318 buffer.serialize_int8(static_cast<std::int8_t>(value));
319 }
320};
321
327template <typename T>
329 std::enable_if_t<details::is_signed_integer_v<T> && sizeof(T) == 2U>> {
330public:
337 static void serialize(serialization_buffer& buffer, T value) {
338 if (value >= static_cast<T>(0)) {
339 serialize_positive_integer(buffer, value);
340 } else {
341 serialize_negative_integer(buffer, value);
342 }
343 }
344
345private:
353 serialization_buffer& buffer, T value) {
354 constexpr T uint8_mask = ~details::max_uint8<T>;
355 if ((value & uint8_mask) == static_cast<T>(0)) {
356 constexpr T positive_fixint_mask = ~details::max_positive_fixint<T>;
357 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
359 static_cast<std::uint8_t>(value));
360 return;
361 }
362
363 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
364 return;
365 }
366
367 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
368 }
369
377 serialization_buffer& buffer, T value) {
378 constexpr T int8_mask = details::min_int8<T>;
379 if ((value & int8_mask) == int8_mask) {
380 constexpr T negative_fixint_mask = details::min_negative_fixint<T>;
381 if ((value & negative_fixint_mask) == negative_fixint_mask) {
383 static_cast<std::int8_t>(value));
384 return;
385 }
386
387 buffer.serialize_int8(static_cast<std::int8_t>(value));
388 return;
389 }
390
391 buffer.serialize_int16(static_cast<std::int16_t>(value));
392 }
393};
394
400template <typename T>
402 std::enable_if_t<details::is_signed_integer_v<T> && sizeof(T) == 4U>> {
403public:
410 static void serialize(serialization_buffer& buffer, T value) {
411 if (value >= static_cast<T>(0)) {
412 serialize_positive_integer(buffer, value);
413 } else {
414 serialize_negative_integer(buffer, value);
415 }
416 }
417
418private:
426 serialization_buffer& buffer, T value) {
427 constexpr T uint8_mask = ~details::max_uint8<T>;
428 if ((value & uint8_mask) == static_cast<T>(0)) {
429 constexpr T positive_fixint_mask = ~details::max_positive_fixint<T>;
430 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
432 static_cast<std::uint8_t>(value));
433 return;
434 }
435
436 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
437 return;
438 }
439
440 constexpr T uint16_mask = ~details::max_uint16<T>;
441 if ((value & uint16_mask) == static_cast<T>(0)) {
442 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
443 return;
444 }
445
446 buffer.serialize_uint32(static_cast<std::uint32_t>(value));
447 }
448
456 serialization_buffer& buffer, T value) {
457 constexpr T int8_mask = details::min_int8<T>;
458 if ((value & int8_mask) == int8_mask) {
459 constexpr T negative_fixint_mask = details::min_negative_fixint<T>;
460 if ((value & negative_fixint_mask) == negative_fixint_mask) {
462 static_cast<std::int8_t>(value));
463 return;
464 }
465
466 buffer.serialize_int8(static_cast<std::int8_t>(value));
467 return;
468 }
469
470 constexpr T int16_mask = details::min_int16<T>;
471 if ((value & int16_mask) == int16_mask) {
472 buffer.serialize_int16(static_cast<std::int16_t>(value));
473 return;
474 }
475
476 buffer.serialize_int32(static_cast<std::int32_t>(value));
477 }
478};
479
485template <typename T>
487 std::enable_if_t<details::is_signed_integer_v<T> &&
488 // NOLINTNEXTLINE(readability-magic-numbers)
489 sizeof(T) == 8U>> {
490public:
497 static void serialize(serialization_buffer& buffer, T value) {
498 if (value >= static_cast<T>(0)) {
499 serialize_positive_integer(buffer, value);
500 } else {
501 serialize_negative_integer(buffer, value);
502 }
503 }
504
505private:
513 serialization_buffer& buffer, T value) {
514 constexpr T uint16_mask = ~details::max_uint16<T>;
515 if ((value & uint16_mask) == static_cast<T>(0)) {
516 constexpr T uint8_mask = ~details::max_uint8<T>;
517 if ((value & uint8_mask) == static_cast<T>(0)) {
518 constexpr T positive_fixint_mask =
519 ~details::max_positive_fixint<T>;
520 if ((value & positive_fixint_mask) == static_cast<T>(0)) {
522 static_cast<std::uint8_t>(value));
523 return;
524 }
525
526 buffer.serialize_uint8(static_cast<std::uint8_t>(value));
527 return;
528 }
529
530 buffer.serialize_uint16(static_cast<std::uint16_t>(value));
531 return;
532 }
533
534 constexpr T uint32_mask = ~details::max_uint32<T>;
535 if ((value & uint32_mask) == static_cast<T>(0)) {
536 buffer.serialize_uint32(static_cast<std::uint32_t>(value));
537 return;
538 }
539 buffer.serialize_uint64(static_cast<std::uint64_t>(value));
540 }
541
549 serialization_buffer& buffer, T value) {
550 constexpr T int16_mask = details::min_int16<T>;
551 if ((value & int16_mask) == int16_mask) {
552 constexpr T int8_mask = details::min_int8<T>;
553 if ((value & int8_mask) == int8_mask) {
554 constexpr T negative_fixint_mask =
556 if ((value & negative_fixint_mask) == negative_fixint_mask) {
558 static_cast<std::int8_t>(value));
559 return;
560 }
561
562 buffer.serialize_int8(static_cast<std::int8_t>(value));
563 return;
564 }
565
566 buffer.serialize_int16(static_cast<std::int16_t>(value));
567 return;
568 }
569
570 constexpr T int32_mask = details::min_int32<T>;
571 if ((value & int32_mask) == int32_mask) {
572 buffer.serialize_int32(static_cast<std::int32_t>(value));
573 return;
574 }
575
576 buffer.serialize_int64(static_cast<std::int64_t>(value));
577 }
578};
579
580} // namespace msgpack_light::type_support
Class of buffers to serialize data.
void serialize_int16(std::int16_t value)
Serialize a value in int 16 format.
void serialize_uint16(std::uint16_t value)
Serialize a value in uint 16 format.
void serialize_uint8(std::uint8_t value)
Serialize a value in uint 8 format.
void serialize_positive_fixint(std::uint8_t value)
Serialize a value in positive fixint format.
void serialize_negative_fixint(std::int8_t value)
Serialize a value in negative fixint format.
void serialize_int64(std::int64_t value)
Serialize a value in int 64 format.
void serialize_uint32(std::uint32_t value)
Serialize a value in uint 32 format.
void serialize_uint64(std::uint64_t value)
Serialize a value in uint 64 format.
void serialize_int32(std::int32_t value)
Serialize a value in int 32 format.
void serialize_int8(std::int8_t value)
Serialize a value in int 8 format.
Forward declaration of classes to support serialization of data types.
Namespace of internal implementations.
constexpr auto min_int16
Minimum value in int 16 format.
Definition integer.h:114
constexpr auto max_uint32
Maximum value in uint 32 format.
Definition integer.h:86
constexpr auto min_int8
Minimum value in int 8 format.
Definition integer.h:104
constexpr auto min_int32
Minimum value in int 32 format.
Definition integer.h:122
constexpr bool is_integer_v
Check whether a type is an integer.
Definition integer.h:38
constexpr bool is_unsigned_integer_v
Check whether a type is an unsigned integer.
Definition integer.h:54
constexpr auto max_uint16
Maximum value in uint 16 format.
Definition integer.h:78
constexpr auto max_positive_fixint
Maximum value in positive fixint format.
Definition integer.h:62
constexpr auto min_negative_fixint
Minimum value in negative fixint format.
Definition integer.h:94
constexpr auto max_uint8
Maximum value in uint 8 format.
Definition integer.h:70
constexpr bool is_signed_integer_v
Check whether a type is a signed integer.
Definition integer.h:46
Namespace of classes to support serialization of types.
Definition array.h:29
STL namespace.
Definition of serialization_buffer class.
static void serialize_positive_integer(serialization_buffer &buffer, T value)
Serialize a positive integers.
Definition integer.h:352
static void serialize_negative_integer(serialization_buffer &buffer, T value)
Serialize a negative integers.
Definition integer.h:376
static void serialize_positive_integer(serialization_buffer &buffer, T value)
Serialize a positive integers.
Definition integer.h:425
static void serialize_negative_integer(serialization_buffer &buffer, T value)
Serialize a negative integers.
Definition integer.h:455
static void serialize_positive_integer(serialization_buffer &buffer, T value)
Serialize a positive integers.
Definition integer.h:512
static void serialize_negative_integer(serialization_buffer &buffer, T value)
Serialize a negative integers.
Definition integer.h:548
static void serialize_positive_integer(serialization_buffer &buffer, T value)
Serialize a positive integers.
Definition integer.h:299
static void serialize_negative_integer(serialization_buffer &buffer, T value)
Serialize a negative integers.
Definition integer.h:310
Class to define functions to serialize data of various types.
Definition fwd.h:43