#pragma once #include #include #include #include namespace gp { enum class cbor_type { uint = 0, nint = 1, bstr = 2, tstr = 3, list = 4, hmap = 5, tags = 6, oths = 7 }; enum class cbor_oths { value_false = 20, value_true = 21, value_null = 22, value_undefined = 23, byte = 24, word = 25, dword = 26, qword = 27, terminator = 31 }; enum class cbor_tags { datetime = 0, unix_time = 1, ubignum = 2, nbignum = 3, decimal = 4, bigfloat = 5, cose_encrypt0 = 16, cose_mac0 = 17, cose_sign1 = 18, expected_base64url = 21, expected_base64 = 22, expected_base16 = 23, encoded_cbor = 24, url = 32, base64url = 33, base64 = 34, regexp = 35, mime = 36, cose_encrypt = 96, cose_mac = 97, cose_sign = 98, signature = 55799 }; using cbor_number = gp::fixed_variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t >; using cbor_floating_point = gp::fixed_variant< float, double >; struct undefined_t final {}; template using cbor_composite = gp::fixed_variant< cbor_number, gp::buffer, bool, gp::vector, gp::vector>, gp::nullopt_t, undefined_t, cbor_floating_point >; class cbor_value { cbor_composite contents; gp::reference_wrapper alloc; public: cbor_value(allocator& alloc_v) : contents(cbor_composite(undefined_t{})) , alloc(alloc_v) {} cbor_value(cbor_number number, allocator& alloc_v) : contents(number) , alloc(alloc_v) {} cbor_value(const cbor_value& oth) : contents(oth.contents) , alloc(oth.alloc) {} cbor_value(cbor_value&& oth) : contents(gp::move(oth.contents)) , alloc(gp::move(oth.alloc)) {} cbor_value& operator=(cbor_value& value) { contents = value.contents; alloc = value.alloc; return *this; } cbor_value& operator=(cbor_value&& value) { gp::swap(contents, value.contents); gp::swap(alloc, value.alloc); return *this; } cbor_value& operator=(cbor_composite& value) { contents = value; return *this; } template cbor_value& operator=(T& value) { contents = value; return *this; } template cbor_value& operator=(T&& value) { contents = gp::move(value); return *this; } auto new_array() { return gp::vector{alloc}; } auto new_object() { return gp::vector>{alloc}; } }; }