From 4bb6c3a4ba75bed30b3a4de9dfb76fe9339a2959 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 18:03:08 +0300 Subject: [PATCH 01/19] update: copyright comments --- CMakeLists.txt | 3 ++- include/scale/bitvec.hpp | 3 ++- include/scale/buffer/buffer.hpp | 3 ++- include/scale/buffer/buffer_back_insert_iterator.hpp | 3 ++- include/scale/buffer/hexutil.hpp | 3 ++- include/scale/detail/fixed_width_integer.hpp | 3 ++- include/scale/detail/variant.hpp | 3 ++- include/scale/encode_append.hpp | 3 ++- include/scale/enum_traits.hpp | 3 ++- include/scale/outcome/outcome-register.hpp | 3 ++- include/scale/outcome/outcome.hpp | 3 ++- include/scale/outcome/outcome_throw.hpp | 3 ++- include/scale/scale.hpp | 3 ++- include/scale/scale_decoder_stream.hpp | 3 ++- include/scale/scale_encoder_stream.hpp | 3 ++- include/scale/scale_error.hpp | 3 ++- include/scale/types.hpp | 3 ++- include/scale/unreachable.hpp | 7 ++++--- include/scale/visitor.hpp | 3 ++- src/buffer/buffer.cpp | 3 ++- src/buffer/hexutil.cpp | 3 ++- src/compact_len_utils.hpp | 3 ++- src/encode_append.cpp | 3 ++- src/scale_decoder_stream.cpp | 3 ++- src/scale_encoder_stream.cpp | 3 ++- src/scale_error.cpp | 3 ++- test/CMakeLists.txt | 3 ++- test/append_test_data.hpp | 3 ++- test/scale_array_test.cpp | 3 ++- test/scale_boolean_test.cpp | 3 ++- test/scale_collection_test.cpp | 3 ++- test/scale_compact_test.cpp | 3 ++- test/scale_convenience_functions_test.cpp | 3 ++- test/scale_decoder_stream_test.cpp | 3 ++- test/scale_encode_append_test.cpp | 3 ++- test/scale_encode_counter_test.cpp | 3 ++- test/scale_enum_test.cpp | 3 ++- test/scale_fixed_test.cpp | 3 ++- test/scale_optional_test.cpp | 3 ++- test/scale_pair_test.cpp | 3 ++- test/scale_strings_test.cpp | 3 ++- test/scale_tuple_test.cpp | 3 ++- test/scale_variant_test.cpp | 3 ++- test/util/literals.hpp | 3 ++- test/util/outcome.hpp | 3 ++- 45 files changed, 92 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf9e32c..e259771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ # -# Copyright Soramitsu Co., Ltd. All Rights Reserved. +# Copyright Quadrivium LLC +# All Rights Reserved # SPDX-License-Identifier: Apache-2.0 # diff --git a/include/scale/bitvec.hpp b/include/scale/bitvec.hpp index 995d22e..1db3154 100644 --- a/include/scale/bitvec.hpp +++ b/include/scale/bitvec.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/buffer/buffer.hpp b/include/scale/buffer/buffer.hpp index b734473..d3edcce 100644 --- a/include/scale/buffer/buffer.hpp +++ b/include/scale/buffer/buffer.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/buffer/buffer_back_insert_iterator.hpp b/include/scale/buffer/buffer_back_insert_iterator.hpp index 9aa62a0..5d41b26 100644 --- a/include/scale/buffer/buffer_back_insert_iterator.hpp +++ b/include/scale/buffer/buffer_back_insert_iterator.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp index f65a17b..9d8e97f 100644 --- a/include/scale/buffer/hexutil.hpp +++ b/include/scale/buffer/hexutil.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/detail/fixed_width_integer.hpp b/include/scale/detail/fixed_width_integer.hpp index 19aabb0..4c92b77 100644 --- a/include/scale/detail/fixed_width_integer.hpp +++ b/include/scale/detail/fixed_width_integer.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/detail/variant.hpp b/include/scale/detail/variant.hpp index c8c944e..2218cb0 100644 --- a/include/scale/detail/variant.hpp +++ b/include/scale/detail/variant.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/encode_append.hpp b/include/scale/encode_append.hpp index 6291662..1082540 100644 --- a/include/scale/encode_append.hpp +++ b/include/scale/encode_append.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/enum_traits.hpp b/include/scale/enum_traits.hpp index 44b28a3..7203e7a 100644 --- a/include/scale/enum_traits.hpp +++ b/include/scale/enum_traits.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/outcome/outcome-register.hpp b/include/scale/outcome/outcome-register.hpp index 2aaa96e..2bbee90 100644 --- a/include/scale/outcome/outcome-register.hpp +++ b/include/scale/outcome/outcome-register.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/outcome/outcome.hpp b/include/scale/outcome/outcome.hpp index 1c0c291..75aa1f7 100644 --- a/include/scale/outcome/outcome.hpp +++ b/include/scale/outcome/outcome.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/outcome/outcome_throw.hpp b/include/scale/outcome/outcome_throw.hpp index c6b9dcc..5e00777 100644 --- a/include/scale/outcome/outcome_throw.hpp +++ b/include/scale/outcome/outcome_throw.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/scale.hpp b/include/scale/scale.hpp index 61156fc..4331a36 100644 --- a/include/scale/scale.hpp +++ b/include/scale/scale.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index cf21e10..3698e70 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index 1b439e2..da5604f 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/scale_error.hpp b/include/scale/scale_error.hpp index cea1683..2770b6e 100644 --- a/include/scale/scale_error.hpp +++ b/include/scale/scale_error.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/types.hpp b/include/scale/types.hpp index d684ec7..bc4b3ea 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/scale/unreachable.hpp b/include/scale/unreachable.hpp index e194c74..456aef3 100644 --- a/include/scale/unreachable.hpp +++ b/include/scale/unreachable.hpp @@ -1,7 +1,8 @@ /** -* Copyright Soramitsu Co., Ltd. All Rights Reserved. -* SPDX-License-Identifier: Apache-2.0 -*/ + * Copyright Quadrivium LLC + * All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef SCALE_UNREACHABLE_HPP #define SCALE_UNREACHABLE_HPP diff --git a/include/scale/visitor.hpp b/include/scale/visitor.hpp index 5bdbf92..13364cc 100644 --- a/include/scale/visitor.hpp +++ b/include/scale/visitor.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/buffer/buffer.cpp b/src/buffer/buffer.cpp index d4dee0a..273b0ff 100644 --- a/src/buffer/buffer.cpp +++ b/src/buffer/buffer.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/buffer/hexutil.cpp b/src/buffer/hexutil.cpp index 9bce4b1..4d5dfc4 100644 --- a/src/buffer/hexutil.cpp +++ b/src/buffer/hexutil.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/compact_len_utils.hpp b/src/compact_len_utils.hpp index aa79b51..0d9d51a 100644 --- a/src/compact_len_utils.hpp +++ b/src/compact_len_utils.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/encode_append.cpp b/src/encode_append.cpp index 8542513..1cd3b3a 100644 --- a/src/encode_append.cpp +++ b/src/encode_append.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/scale_decoder_stream.cpp b/src/scale_decoder_stream.cpp index fb7c734..483096f 100644 --- a/src/scale_decoder_stream.cpp +++ b/src/scale_decoder_stream.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/scale_encoder_stream.cpp b/src/scale_encoder_stream.cpp index 3537550..9bbc082 100644 --- a/src/scale_encoder_stream.cpp +++ b/src/scale_encoder_stream.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/scale_error.cpp b/src/scale_error.cpp index c60748a..0e70e62 100644 --- a/src/scale_error.cpp +++ b/src/scale_error.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8b6fba1..49a90ab 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ ## -# Copyright Soramitsu Co., Ltd. All Rights Reserved. +# Copyright Quadrivium LLC +# All Rights Reserved # SPDX-License-Identifier: Apache-2.0 ## diff --git a/test/append_test_data.hpp b/test/append_test_data.hpp index 213915d..bb91886 100644 --- a/test/append_test_data.hpp +++ b/test/append_test_data.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_array_test.cpp b/test/scale_array_test.cpp index 48161d2..9acbae4 100644 --- a/test/scale_array_test.cpp +++ b/test/scale_array_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_boolean_test.cpp b/test/scale_boolean_test.cpp index c6638ca..5b031be 100644 --- a/test/scale_boolean_test.cpp +++ b/test/scale_boolean_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index e03c1d5..66477b8 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_compact_test.cpp b/test/scale_compact_test.cpp index 3cef639..dfa6ef6 100644 --- a/test/scale_compact_test.cpp +++ b/test/scale_compact_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_convenience_functions_test.cpp b/test/scale_convenience_functions_test.cpp index ac16fa6..cdde3ff 100644 --- a/test/scale_convenience_functions_test.cpp +++ b/test/scale_convenience_functions_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_decoder_stream_test.cpp b/test/scale_decoder_stream_test.cpp index acbe832..40fce01 100644 --- a/test/scale_decoder_stream_test.cpp +++ b/test/scale_decoder_stream_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ #include diff --git a/test/scale_encode_append_test.cpp b/test/scale_encode_append_test.cpp index 6cc837f..8e024c3 100644 --- a/test/scale_encode_append_test.cpp +++ b/test/scale_encode_append_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_encode_counter_test.cpp b/test/scale_encode_counter_test.cpp index 8362c2f..fd18412 100644 --- a/test/scale_encode_counter_test.cpp +++ b/test/scale_encode_counter_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_enum_test.cpp b/test/scale_enum_test.cpp index 807fe6a..409579b 100644 --- a/test/scale_enum_test.cpp +++ b/test/scale_enum_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_fixed_test.cpp b/test/scale_fixed_test.cpp index 50bec84..ba7db5d 100644 --- a/test/scale_fixed_test.cpp +++ b/test/scale_fixed_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_optional_test.cpp b/test/scale_optional_test.cpp index 1312501..1a79918 100644 --- a/test/scale_optional_test.cpp +++ b/test/scale_optional_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_pair_test.cpp b/test/scale_pair_test.cpp index 59233fa..a33cd85 100644 --- a/test/scale_pair_test.cpp +++ b/test/scale_pair_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_strings_test.cpp b/test/scale_strings_test.cpp index 478cb1f..f1b6277 100644 --- a/test/scale_strings_test.cpp +++ b/test/scale_strings_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_tuple_test.cpp b/test/scale_tuple_test.cpp index e3f8d37..df47882 100644 --- a/test/scale_tuple_test.cpp +++ b/test/scale_tuple_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/scale_variant_test.cpp b/test/scale_variant_test.cpp index f419247..f9610de 100644 --- a/test/scale_variant_test.cpp +++ b/test/scale_variant_test.cpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/util/literals.hpp b/test/util/literals.hpp index 0381e74..01c3256 100644 --- a/test/util/literals.hpp +++ b/test/util/literals.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ diff --git a/test/util/outcome.hpp b/test/util/outcome.hpp index b3bc667..6d81677 100644 --- a/test/util/outcome.hpp +++ b/test/util/outcome.hpp @@ -1,5 +1,6 @@ /** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * Copyright Quadrivium LLC + * All Rights Reserved * SPDX-License-Identifier: Apache-2.0 */ From 5b975b6ce21b2c0a0656d846bd6df7544645c8c6 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 18:40:32 +0300 Subject: [PATCH 02/19] update: hunter --- CMakeLists.txt | 4 ++-- test/installation/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e259771..711603a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,8 @@ cmake_minimum_required(VERSION 3.12) include(${CMAKE_CURRENT_LIST_DIR}/cmake/HunterGate.cmake) HunterGate( - URL "https://github.com/soramitsu/soramitsu-hunter/archive/v0.23.257-soramitsu42.tar.gz" - SHA1 "6f54ad82c2322ff0e234ab96a44a12da1478f1be" + URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.23.257-qdrvm10.tar.gz + SHA1 72b446a4424ba28ea90f9a68a9134b0f8e44b5b2 ) project(Scale LANGUAGES CXX VERSION 1.0.0) diff --git a/test/installation/CMakeLists.txt b/test/installation/CMakeLists.txt index f9e3151..6eb5124 100644 --- a/test/installation/CMakeLists.txt +++ b/test/installation/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.12) include(../../cmake/HunterGate.cmake) HunterGate( - URL https://github.com/soramitsu/soramitsu-hunter/archive/master.tar.gz - SHA1 39113c56b1d6be190b13995348816710dc1715f7 + URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.23.257-qdrvm10.tar.gz + SHA1 72b446a4424ba28ea90f9a68a9134b0f8e44b5b2 ) project(ScaleTest CXX) From 17e28e1696c5193999d695e377170329740bf34c Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 18:41:10 +0300 Subject: [PATCH 03/19] update: bump C++ standard up to C++20 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 711603a..0c13edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ HunterGate( project(Scale LANGUAGES CXX VERSION 1.0.0) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) From dc712526152e4aebcafee899f9241e346b959d05 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 18:46:29 +0300 Subject: [PATCH 04/19] refactor: gsl::span replaced by std::span refactor: containers replaced by range (where it possible) refactor: clang-format --- README.md | 2 +- include/scale/buffer/buffer.hpp | 484 +++++++++--------- .../buffer/buffer_back_insert_iterator.hpp | 122 ++--- include/scale/buffer/hexutil.hpp | 15 +- include/scale/detail/fixed_width_integer.hpp | 4 +- include/scale/detail/variant.hpp | 12 +- include/scale/encode_append.hpp | 9 +- include/scale/outcome/outcome-register.hpp | 121 +++-- include/scale/outcome/outcome.hpp | 15 +- include/scale/scale.hpp | 9 +- include/scale/scale_decoder_stream.hpp | 10 +- include/scale/scale_encoder_stream.hpp | 47 +- include/scale/scale_error.hpp | 10 +- include/scale/types.hpp | 37 +- include/scale/unreachable.hpp | 2 +- include/scale/visitor.hpp | 6 +- src/buffer/buffer.cpp | 45 +- src/buffer/hexutil.cpp | 15 +- src/compact_len_utils.hpp | 2 +- src/encode_append.cpp | 2 +- src/scale_decoder_stream.cpp | 5 - src/scale_error.cpp | 4 +- test/scale_boolean_test.cpp | 6 +- test/scale_collection_test.cpp | 22 +- test/scale_compact_test.cpp | 4 +- test/scale_convenience_functions_test.cpp | 7 +- test/scale_encode_counter_test.cpp | 4 +- test/scale_strings_test.cpp | 26 +- test/scale_tuple_test.cpp | 3 +- test/scale_variant_test.cpp | 1 - test/util/literals.hpp | 1 - test/util/outcome.hpp | 2 +- 32 files changed, 516 insertions(+), 538 deletions(-) diff --git a/README.md b/README.md index b84d492..1fb63c7 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ template outcome::result> encode(T &&t); template -outcome::result decode(gsl::span span) +outcome::result decode(const RangeOfBytes auto& span) template outcome::result decode(ScaleDecoderStream &s) diff --git a/include/scale/buffer/buffer.hpp b/include/scale/buffer/buffer.hpp index d3edcce..eab39f1 100644 --- a/include/scale/buffer/buffer.hpp +++ b/include/scale/buffer/buffer.hpp @@ -12,274 +12,250 @@ #include #include -#include #include +#include namespace scale { -/** - * @brief Class represents arbitrary (including empty) byte buffer. - */ -class Buffer : public boost::equality_comparable, - public boost::equality_comparable>, - public boost::equality_comparable>, - public boost::less_than_comparable { -public: - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; - using value_type = uint8_t; - // with this gsl::span can be built from Buffer - using pointer = typename std::vector::pointer; - using const_pointer = typename std::vector::const_pointer; - - /** - * @brief allocates buffer of size={@param size}, filled with {@param byte} - */ - Buffer(size_t size, uint8_t byte); - - ~Buffer() = default; - - /** - * @brief lvalue construct buffer from a byte vector - */ - explicit Buffer(std::vector v); - explicit Buffer(gsl::span s); - - Buffer(const uint8_t *begin, const uint8_t *end); - - Buffer() = default; - Buffer(const Buffer &b) = default; - Buffer(Buffer &&b) noexcept = default; - Buffer(std::initializer_list b); - - Buffer &reserve(size_t size); - Buffer &resize(size_t size); - - Buffer &operator=(const Buffer &other) = default; - Buffer &operator=(Buffer &&other) noexcept = default; - - Buffer &operator+=(const Buffer &other) noexcept; - - /** - * @brief Accessor of byte elements given {@param index} in bytearray - */ - uint8_t operator[](size_t index) const; - - /** - * @brief Accessor of byte elements given {@param index} in bytearray - */ - uint8_t &operator[](size_t index); - - /** - * @brief Lexicographical comparison of two buffers - */ - bool operator==(const Buffer &b) const noexcept; - - /** - * @brief Lexicographical comparison of buffer and vector of bytes - */ - bool operator==(const std::vector &b) const noexcept; - - /** - * @brief Lexicographical comparison of buffer and vector of bytes - */ - bool operator==(gsl::span s) const noexcept; - - /** - * @brief Lexicographical comparison of two buffers - */ - bool operator<(const Buffer &b) const noexcept; - - /** - * @brief Iterator, which points to begin of this buffer. - */ - iterator begin(); - - /** - * @brief Iterator, which points to the element next to the last in this - * buffer. - */ - iterator end(); - - /** - * @brief Iterator, which points to begin of this buffer. - */ - const_iterator begin() const; - - /** - * @brief Iterator, which points to the element next to the last in this - * buffer. - */ - const_iterator end() const; - - /** - * @brief Getter for size of this buffer. - */ - size_t size() const; - - /** - * @brief Put a 8-bit {@param n} in this buffer. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint8(uint8_t n); - - /** - * @brief Put a 32-bit {@param n} number in this buffer. Will be serialized - * as big-endian number. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint32(uint32_t n); - - /** - * @brief Put a 64-bit {@param n} number in this buffer. Will be serialized - * as big-endian number. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint64(uint64_t n); - - /** - * @brief Put a string into byte buffer - * @param s arbitrary string - * @return this buffer, suitable for chaining. - */ - Buffer &put(std::string_view str); - /** - * @brief Put a vector of bytes into byte buffer - * @param s arbitrary vector of bytes - * @return this buffer, suitable for chaining. + * @brief Class represents arbitrary (including empty) byte buffer. */ - Buffer &put(const std::vector &v); + class Buffer : public boost::equality_comparable, + public boost::equality_comparable, + public boost::equality_comparable>, + public boost::less_than_comparable { + public: + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using value_type = uint8_t; + // with this gsl::span can be built from Buffer + using pointer = typename std::vector::pointer; + using const_pointer = typename std::vector::const_pointer; + + /** + * @brief allocates buffer of size={@param size}, filled with {@param byte} + */ + Buffer(size_t size, uint8_t byte); + + ~Buffer() = default; + + /** + * @brief lvalue construct buffer from a byte vector + */ + explicit Buffer(std::vector vector); + explicit Buffer(const RangeOfBytes auto &range); + + Buffer(const uint8_t *begin, const uint8_t *end); + + Buffer() = default; + Buffer(const Buffer &b) = default; + Buffer(Buffer &&b) noexcept = default; + Buffer(std::initializer_list il); + + Buffer &reserve(size_t size); + Buffer &resize(size_t size); + + Buffer &operator=(const Buffer &other) = default; + Buffer &operator=(Buffer &&other) noexcept = default; + + Buffer &operator+=(const Buffer &other) noexcept; + + /** + * @brief Accessor of byte elements given {@param index} in bytearray + */ + uint8_t operator[](size_t index) const; + + /** + * @brief Accessor of byte elements given {@param index} in bytearray + */ + uint8_t &operator[](size_t index); + + /** + * @brief Lexicographical comparison of buffer content and range of bytes + */ + bool operator==(const RangeOfBytes auto &other) const noexcept; + + /** + * @brief Lexicographical comparison of buffer content and range of bytes + */ + bool operator<(const RangeOfBytes auto &other) const noexcept; + + /** + * @brief Iterator, which points to begin of this buffer. + */ + iterator begin(); + + /** + * @brief Iterator, which points to the element next to the last in this + * buffer. + */ + iterator end(); + + /** + * @brief Iterator, which points to begin of this buffer. + */ + const_iterator begin() const; + + /** + * @brief Iterator, which points to the element next to the last in this + * buffer. + */ + const_iterator end() const; + + /** + * @brief Getter for size of this buffer. + */ + size_t size() const; + + /** + * @brief Put a 8-bit {@param n} in this buffer. + * @return this buffer, suitable for chaining. + */ + Buffer &putUint8(uint8_t n); + + /** + * @brief Put a 32-bit {@param n} number in this buffer. Will be serialized + * as big-endian number. + * @return this buffer, suitable for chaining. + */ + Buffer &putUint32(uint32_t n); + + /** + * @brief Put a 64-bit {@param n} number in this buffer. Will be serialized + * as big-endian number. + * @return this buffer, suitable for chaining. + */ + Buffer &putUint64(uint64_t n); + + /** + * @brief Put a sequence of bytes into byte buffer + * @param s arbitrary span of bytes + * @return this buffer, suitable for chaining. + */ + Buffer &put(const RangeOfBytes auto &range); + + /** + * @brief Put a array of bytes bounded by pointers into byte buffer + * @param begin pointer to the array start + * end pointer to the address after the last element + * @return this buffer, suitable for chaining. + */ + Buffer &putBytes(const uint8_t *begin, const uint8_t *end); + + [[deprecated("Use Buffer::put() instead that")]] Buffer &putBuffer( + const Buffer &buf); + + /** + * Clear the contents of the Buffer + */ + void clear(); + + /** + * @brief getter for raw array of bytes + */ + const uint8_t *data() const; + uint8_t *data(); + + /** + * @brief getter for vector of bytes + */ + const std::vector &toVector() const; + + std::vector &toVector(); + + /** + * Returns a copy of a part of the buffer + * Works alike subspan() of gsl::span + */ + Buffer subbuffer(size_t offset = 0, size_t length = -1) const; + + /** + * @brief encode bytearray as hex + * @return hex-encoded string + */ + std::string toHex() const; + + /** + * Check if this buffer is empty + * @return true, if buffer is empty, false otherwise + */ + bool empty() const; + + /** + * @brief Construct Buffer from hex string + * @param hex hex-encoded string + * @return result containing constructed buffer if input string is + * hex-encoded string. + */ + static outcome::result fromHex(std::string_view hex); + + /** + * @brief return content of bytearray as string + * @note Does not ensure correct encoding + * @return string + */ + std::string_view toString() const; + + /** + * @brief return content of bytearray as a string copy data + * @note Does not ensure correct encoding + * @return string + */ + std::string asString() const; + + /** + * @brief stores content of a string to byte array + */ + static outcome::result fromString(const std::string &src); + + private: + std::vector data_; + + template + Buffer &putRange(const T &begin, const T &end); + }; /** - * @brief Put a sequence of bytes into byte buffer - * @param s arbitrary span of bytes - * @return this buffer, suitable for chaining. + * @brief override operator<< for all streams except std::ostream + * @tparam Stream stream type + * @param s stream reference + * @param buffer value to encode + * @return reference to stream */ - Buffer &put(gsl::span s); - - /** - * @brief Put a array of bytes bounded by pointers into byte buffer - * @param begin pointer to the array start - * end pointer to the address after the last element - * @return this buffer, suitable for chaining. - */ - Buffer &putBytes(const uint8_t *begin, const uint8_t *end); - - /** - * @brief Put another buffer content at the end of current one - * @param buf another buffer - * @return this buffer suitable for chaining. - */ - Buffer &putBuffer(const Buffer &buf); - - /** - * Clear the contents of the Buffer - */ - void clear(); - - /** - * @brief getter for raw array of bytes - */ - const uint8_t *data() const; - uint8_t *data(); - - /** - * @brief getter for vector of bytes - */ - const std::vector &toVector() const; - - std::vector &toVector(); - - /** - * Returns a copy of a part of the buffer - * Works alike subspan() of gsl::span - */ - Buffer subbuffer(size_t offset = 0, size_t length = -1) const; - - /** - * @brief encode bytearray as hex - * @return hex-encoded string - */ - std::string toHex() const; - - /** - * Check if this buffer is empty - * @return true, if buffer is empty, false otherwise - */ - bool empty() const; - - /** - * @brief Construct Buffer from hex string - * @param hex hex-encoded string - * @return result containing constructed buffer if input string is - * hex-encoded string. - */ - static outcome::result fromHex(std::string_view hex); - - /** - * @brief return content of bytearray as string - * @note Does not ensure correct encoding - * @return string - */ - std::string_view toString() const; - - /** - * @brief return content of bytearray as a string copy data - * @note Does not ensure correct encoding - * @return string - */ - std::string asString() const; + template > + Stream &operator<<(Stream &s, const Buffer &buffer) { + return s << buffer.toVector(); + } /** - * @brief stores content of a string to byte array + * @brief decodes buffer object from stream + * @tparam Stream input stream type + * @param s stream reference + * @param buffer value to decode + * @return reference to stream */ - static outcome::result fromString(const std::string &src); - -private: - std::vector data_; - - template Buffer &putRange(const T &begin, const T &end); -}; - -/** - * @brief override operator<< for all streams except std::ostream - * @tparam Stream stream type - * @param s stream reference - * @param buffer value to encode - * @return reference to stream - */ -template > -Stream &operator<<(Stream &s, const Buffer &buffer) { - return s << buffer.toVector(); -} - -/** - * @brief decodes buffer object from stream - * @tparam Stream input stream type - * @param s stream reference - * @param buffer value to decode - * @return reference to stream - */ -template > -Stream &operator>>(Stream &s, Buffer &buffer) { - std::vector data; - s >> data; - buffer.put(data); - return s; -} + template > + Stream &operator>>(Stream &s, Buffer &buffer) { + std::vector data; + s >> data; + buffer.put(data); + return s; + } -std::ostream &operator<<(std::ostream &os, const Buffer &buffer); + std::ostream &operator<<(std::ostream &os, const Buffer &buffer); -} // namespace scale::common +} // namespace scale namespace std { -template <> struct hash { - size_t operator()(const scale::Buffer &x) const { - return boost::hash_range(x.begin(), x.end()); - } -}; -} // namespace std - -#endif // SCALE_BUFFER_HPP + template <> + struct hash { + size_t operator()(const scale::Buffer &x) const { + return boost::hash_range(x.begin(), x.end()); + } + }; +} // namespace std + +#endif // SCALE_BUFFER_HPP diff --git a/include/scale/buffer/buffer_back_insert_iterator.hpp b/include/scale/buffer/buffer_back_insert_iterator.hpp index 5d41b26..7c72c5b 100644 --- a/include/scale/buffer/buffer_back_insert_iterator.hpp +++ b/include/scale/buffer/buffer_back_insert_iterator.hpp @@ -10,73 +10,55 @@ using scale::Buffer; namespace std { -/* - * std::back_insert_iterator is an output iterator - * that appends to a container for which it was constructed. - */ -template <> -class back_insert_iterator { -public: - using value_type = Buffer::value_type; - using difference_type = typename std::vector::difference_type; - using pointer = Buffer::pointer; - using reference = typename std::vector::reference; - using iterator_category = std::random_access_iterator_tag; - - constexpr explicit back_insert_iterator(Buffer &c): - buf_ {c} { - } - - back_insert_iterator& - operator=(uint8_t value) { - buf_.putUint8(value); - return *this; - } - - back_insert_iterator& - operator=(uint32_t value) { - buf_.putUint32(value); - return *this; - } - - back_insert_iterator& - operator=(uint64_t value) { - buf_.putUint64(value); - return *this; - } - - back_insert_iterator& - operator=(std::string_view value) { - buf_.put(value); - return *this; - } - - back_insert_iterator& - operator=(gsl::span s) { - buf_.put(s); - return *this; - } - - back_insert_iterator& - operator=(const std::vector& v) { - buf_.put(v); - return *this; - } - - constexpr back_insert_iterator& operator*() { - return *this; - } - - constexpr back_insert_iterator& operator++() { - return *this; - } - - constexpr back_insert_iterator& operator++(int) { - return *this; - } - -private: - Buffer& buf_; -}; - -} + /* + * std::back_insert_iterator is an output iterator + * that appends to a container for which it was constructed. + */ + template <> + class back_insert_iterator { + public: + using value_type = Buffer::value_type; + using difference_type = typename std::vector::difference_type; + using pointer = Buffer::pointer; + using reference = typename std::vector::reference; + using iterator_category = std::random_access_iterator_tag; + + constexpr explicit back_insert_iterator(Buffer &c) : buf_{c} {} + + back_insert_iterator &operator=(uint8_t value) { + buf_.putUint8(value); + return *this; + } + + back_insert_iterator &operator=(uint32_t value) { + buf_.putUint32(value); + return *this; + } + + back_insert_iterator &operator=(uint64_t value) { + buf_.putUint64(value); + return *this; + } + + back_insert_iterator &operator=(const RangeOfBytes auto &range) { + buf_.put(range); + return *this; + } + + constexpr back_insert_iterator &operator*() { + return *this; + } + + constexpr back_insert_iterator &operator++() { + return *this; + } + + constexpr back_insert_iterator &operator++(int) { + return *this; + } + + private: + Buffer &buf_; + }; + +} // namespace std diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp index 9d8e97f..5fd3e14 100644 --- a/include/scale/buffer/hexutil.hpp +++ b/include/scale/buffer/hexutil.hpp @@ -10,9 +10,10 @@ #include #include -#include +#include #include +#include namespace scale { @@ -38,7 +39,7 @@ namespace scale { * @param len length of bytes * @return hexstring */ - std::string hex_upper(gsl::span bytes) noexcept; + std::string hex_upper(const RangeOfBytes auto &bytes) noexcept; /** * @brief Converts bytes to hex representation @@ -46,14 +47,18 @@ namespace scale { * @param len length of bytes * @return hexstring */ - std::string hex_lower(gsl::span bytes) noexcept; + std::string hex_lower(const RangeOfBytes auto &bytes) noexcept { + std::string res(bytes.size() * 2, '\x00'); + boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); + return res; + } /** * @brief Converts bytes to hex representation with prefix 0x * @param array bytes * @return hexstring */ - std::string hex_lower_0x(gsl::span bytes) noexcept; + std::string hex_lower_0x(RangeOfBytes auto bytes) noexcept; /** * @brief Converts hex representation to bytes @@ -106,7 +111,7 @@ namespace scale { return result; } -} // namespace scale::common +} // namespace scale OUTCOME_HPP_DECLARE_ERROR_2(scale, UnhexError) diff --git a/include/scale/detail/fixed_width_integer.hpp b/include/scale/detail/fixed_width_integer.hpp index 4c92b77..5439fbe 100644 --- a/include/scale/detail/fixed_width_integer.hpp +++ b/include/scale/detail/fixed_width_integer.hpp @@ -102,6 +102,6 @@ namespace scale::detail { I sv = -static_cast((~v) + 1); return sv; } -} // namespace scale::detail +} // namespace scale::detail -#endif // SCALE_SCALE_UTIL_HPP +#endif // SCALE_SCALE_UTIL_HPP diff --git a/include/scale/detail/variant.hpp b/include/scale/detail/variant.hpp index 2218cb0..9a13e7d 100644 --- a/include/scale/detail/variant.hpp +++ b/include/scale/detail/variant.hpp @@ -38,12 +38,12 @@ namespace scale::detail { template void apply(uint8_t index) { // if type matches alternative in variant then encode - scale::visit_in_place(v_, - [this, index](const H &h) { - s_ << index - << h; // first byte means type index - }, - [](const auto & /*unused*/) {}); + scale::visit_in_place( + v_, + [this, index](const H &h) { + s_ << index << h; // first byte means type index + }, + [](const auto & /*unused*/) {}); } private: diff --git a/include/scale/encode_append.hpp b/include/scale/encode_append.hpp index 1082540..31f7508 100644 --- a/include/scale/encode_append.hpp +++ b/include/scale/encode_append.hpp @@ -15,7 +15,7 @@ namespace scale { * Vector wrapper, that is scale encoded without prepended CompactInteger */ struct EncodeOpaqueValue { - gsl::span v; + ConstSpanOfBytes v; }; template append_or_new_vec(std::vector &self_encoded, - gsl::span input); + ConstSpanOfBytes input); + + inline outcome::result append_or_new_vec( + std::vector &self_encoded, const RangeOfBytes auto &input) { + return append_or_new_vec(self_encoded, ConstSpanOfBytes(input)); + } } // namespace scale #endif // SCALE_CORE_SCALE_ENCODE_APPEND_HPP diff --git a/include/scale/outcome/outcome-register.hpp b/include/scale/outcome/outcome-register.hpp index 2bbee90..4960fea 100644 --- a/include/scale/outcome/outcome-register.hpp +++ b/include/scale/outcome/outcome-register.hpp @@ -8,9 +8,9 @@ #define SCALE_OUTCOME_REGISTER_HPP #include -#include // bring in std::error_code et al +#include // bring in std::error_code et al -#include // for BOOST_SYMBOL_EXPORT +#include // for BOOST_SYMBOL_EXPORT #ifndef SCALE_EXPORT #if defined(BOOST_SYMBOL_EXPORT) @@ -24,78 +24,87 @@ namespace scale::__outcome_detail { -template class Category : public std::error_category { -public: - const char *name() const noexcept final { - return typeid(T).name(); // enum Errc -> 4Errc + template + class Category : public std::error_category { + public: + const char *name() const noexcept final { + return typeid(T).name(); // enum Errc -> 4Errc + } + + std::string message(int c) const final { + return toString(static_cast(c)); + } + + static std::string toString(T t) { + static_assert( + !std::is_same::value, + "toString() was not specialised for the type T supplied"); + return ""; + } + + SCALE_EXPORT static const Category &get() { + static const Category c; + return c; + } + + ~Category() override = default; + Category(const Category &) = delete; + Category &operator=(const Category &) = delete; + Category(Category &&) = delete; + Category &operator=(Category &&) = delete; + + private: + Category() = default; + }; /* end of class */ + +} // namespace scale::__outcome_detail + +#define __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ + extern std::error_code make_error_code(Enum e) { \ + return {static_cast(e), \ + scale::__outcome_detail::Category::get()}; \ } - std::string message(int c) const final { return toString(static_cast(c)); } - - static std::string toString(T t) { - static_assert(!std::is_same::value, - "toString() was not specialised for the type T supplied"); - return ""; - } - - SCALE_EXPORT static const Category &get() { - static const Category c; - return c; - } - - ~Category() override = default; - Category(const Category &) = delete; - Category &operator=(const Category &) = delete; - Category(Category &&) = delete; - Category &operator=(Category &&) = delete; - -private: - Category() = default; -}; /* end of class */ - -} // namespace scale::__outcome_detail - -#define __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ - extern std::error_code make_error_code(Enum e) { \ - return {static_cast(e), scale::__outcome_detail::Category::get()}; \ - } - -#define __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ +#define __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ std::error_code make_error_code(Enum e); /// MUST BE EXECUTED A FILE LEVEL (no namespace) in HPP // ns - fully qualified enum namespace. Example: libp2p::common // Enum - enum name. Example: EncodeError -#define OUTCOME_HPP_DECLARE_ERROR_2(ns, Enum) \ - namespace ns { \ - __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ - } \ - \ - template <> struct std::is_error_code_enum : std::true_type {}; +#define OUTCOME_HPP_DECLARE_ERROR_2(ns, Enum) \ + namespace ns { \ + __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ + } \ + \ + template <> \ + struct std::is_error_code_enum : std::true_type {}; /// MUST BE EXECUTED A FILE LEVEL (global namespace) in HPP // Enum - enum name. Example: EncodeError -#define OUTCOME_HPP_DECLARE_ERROR_1(Enum) \ - __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ - template <> struct std::is_error_code_enum : std::true_type {}; +#define OUTCOME_HPP_DECLARE_ERROR_1(Enum) \ + __OUTCOME_DECLARE_MAKE_ERROR_CODE(Enum) \ + template <> \ + struct std::is_error_code_enum : std::true_type {}; /// MUST BE EXECUTED AT FILE LEVEL(no namespace) IN CPP // ns - fully qualified enum namespace. Example: libp2p::common // Enum - enum name. Example: EncodeError // Name - variable name. Example: e -#define OUTCOME_CPP_DEFINE_CATEGORY_3(ns, Enum, Name) \ - namespace ns { \ - __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ - }; \ - template <> \ - std::string scale::__outcome_detail::Category::toString(ns::Enum Name) +#define OUTCOME_CPP_DEFINE_CATEGORY_3(ns, Enum, Name) \ + namespace ns { \ + __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ + }; \ + template <> \ + std::string scale::__outcome_detail::Category::toString( \ + ns::Enum Name) /// MUST BE EXECUTED AT FILE LEVEL(global namespace) IN CPP // Enum - enum name. Example: EncodeError // Name - variable name. Example: e -#define OUTCOME_CPP_DEFINE_CATEGORY_2(Enum, Name) \ - __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ - template <> std::string scale::__outcome_detail::Category::toString(Enum Name) +#define OUTCOME_CPP_DEFINE_CATEGORY_2(Enum, Name) \ + __OUTCOME_DEFINE_MAKE_ERROR_CODE(Enum) \ + template <> \ + std::string scale::__outcome_detail::Category::toString(Enum Name) // kind of "macro overloading" #define __GET_MACRO_3(_1, _2, _3, NAME, ...) NAME @@ -103,7 +112,7 @@ template class Category : public std::error_category { /// with 3 args: OUTCOME_CPP_DEFINE_CATEGORY_3 /// with 2 args: OUTCOME_CPP_DEFINE_CATEGORY_2 -#define OUTCOME_CPP_DEFINE_CATEGORY(...) \ +#define OUTCOME_CPP_DEFINE_CATEGORY(...) \ OUTCOME_CPP_DEFINE_CATEGORY_3(__VA_ARGS__) /// with 2 args: OUTCOME_CPP_DEFINE_CATEGORY_2 diff --git a/include/scale/outcome/outcome.hpp b/include/scale/outcome/outcome.hpp index 75aa1f7..56c0dbb 100644 --- a/include/scale/outcome/outcome.hpp +++ b/include/scale/outcome/outcome.hpp @@ -8,8 +8,8 @@ #define SCALE_OUTCOME_OUTCOME #pragma warning(push) -#pragma warning(disable:4583) -#pragma warning(disable:4582) +#pragma warning(disable : 4583) +#pragma warning(disable : 4582) #include #include #pragma warning(pop) @@ -18,13 +18,14 @@ namespace scale::outcome { -using namespace BOOST_OUTCOME_V2_NAMESPACE; + using namespace BOOST_OUTCOME_V2_NAMESPACE; -template > -using result = basic_result; + template > + using result = basic_result; -} // namespace scale::outcome +} // namespace scale::outcome // To define OUTCOME_TRY macro, we will need to create OUTCOME_TRY_1 and // OUTCOME_TRY_2 depending on number of arguments diff --git a/include/scale/scale.hpp b/include/scale/scale.hpp index 4331a36..9ccedf0 100644 --- a/include/scale/scale.hpp +++ b/include/scale/scale.hpp @@ -11,12 +11,11 @@ #include #include -#include +#include #include #include #include -#include #define SCALE_EMPTY_DECODER(TargetType) \ template - outcome::result> encode(Args &&... args) { + outcome::result> encode(Args &&...args) { ScaleEncoderStream s{}; try { (s << ... << std::forward(args)); @@ -61,9 +60,9 @@ namespace scale { * @return decoded T */ template - outcome::result decode(gsl::span span) { + outcome::result decode(ConstSpanOfBytes data) { T t{}; - ScaleDecoderStream s(span); + ScaleDecoderStream s(data); try { s >> t; } catch (std::system_error &e) { diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index 3698e70..6023d50 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -12,15 +12,14 @@ #include #include #include +#include #include -#include #include #include +#include #include -#include -#include "scale/types.hpp" namespace scale { class ScaleDecoderStream { @@ -28,7 +27,8 @@ namespace scale { // special tag to differentiate decoding streams from others static constexpr auto is_decoder_stream = true; - explicit ScaleDecoderStream(gsl::span span); + explicit ScaleDecoderStream(ConstSpanOfBytes data) + : span_{data}, current_iterator_{span_.begin()}, current_index_{0} {} /** * @brief scale-decodes pair of values @@ -405,7 +405,7 @@ namespace scale { */ uint8_t nextByte(); - using ByteSpan = gsl::span; + using ByteSpan = ConstSpanOfBytes; using SpanIterator = ByteSpan::iterator; using SizeType = ByteSpan::size_type; diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index da5604f..7b7380f 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -12,10 +12,10 @@ #include #include -#include #include #include +#include namespace scale { @@ -90,14 +90,14 @@ namespace scale { } /** - * @brief scale-encodes gsl::span + * @brief scale-encodes span * @tparam T type of item * @tparam S container size (-1 for dynamic) * @param span span to encode * @return reference to stream */ template - ScaleEncoderStream &operator<<(const gsl::span &span) { + ScaleEncoderStream &operator<<(const std::span &span) { if constexpr (S == -1) { return encodeDynamicCollection( std::size(span), std::begin(span), std::end(span)); @@ -107,25 +107,36 @@ namespace scale { } /** - * @brief scale-encodes collection of same type items, requires bool tag - * is_static_collection - * @tparam C container type, T type of item - * @param c collection to encode + * @brief scale-encodes range + * @param range range to encode * @return reference to stream */ - template > - ScaleEncoderStream &operator<<(const C &c) { - if constexpr (C::is_static_collection) { - return encodeStaticCollection(c); - } else { - return encodeDynamicCollection( - std::size(c), std::begin(c), std::end(c)); - } + ScaleEncoderStream &operator<<(std::ranges::range auto range) { + return encodeDynamicCollection( + std::size(range), std::begin(range), std::end(range)); } + // /** + // * @brief scale-encodes collection of same type items, requires bool + // tag + // * is_static_collection + // * @tparam C container type, T type of item + // * @param c collection to encode + // * @return reference to stream + // */ + // template > + // ScaleEncoderStream &operator<<(const C &c) { + // if constexpr (C::is_static_collection) { + // return encodeStaticCollection(c); + // } else { + // return encodeDynamicCollection( + // std::size(c), std::begin(c), std::end(c)); + // } + // } + ScaleEncoderStream &operator<<(const std::vector &v) { *this << CompactInteger{v.size()}; for (bool el : v) { diff --git a/include/scale/scale_error.hpp b/include/scale/scale_error.hpp index 2770b6e..3d36b13 100644 --- a/include/scale/scale_error.hpp +++ b/include/scale/scale_error.hpp @@ -26,11 +26,11 @@ namespace scale { * @brief DecoderError enum provides codes of errors for Decoder methods */ enum class DecodeError { - NOT_ENOUGH_DATA = 1, ///< not enough data to decode value - UNEXPECTED_VALUE, ///< unexpected value - TOO_MANY_ITEMS, ///< too many items, cannot address them in memory - WRONG_TYPE_INDEX, ///< wrong type index, cannot decode variant - INVALID_ENUM_VALUE ///< enum value which doesn't belong to the enum + NOT_ENOUGH_DATA = 1, ///< not enough data to decode value + UNEXPECTED_VALUE, ///< unexpected value + TOO_MANY_ITEMS, ///< too many items, cannot address them in memory + WRONG_TYPE_INDEX, ///< wrong type index, cannot decode variant + INVALID_ENUM_VALUE ///< enum value which doesn't belong to the enum }; } // namespace scale diff --git a/include/scale/types.hpp b/include/scale/types.hpp index bc4b3ea..013eafd 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -7,28 +7,44 @@ #ifndef SCALE_SCALE_TYPES_HPP #define SCALE_SCALE_TYPES_HPP +#include +#include +#include #include #include #include namespace scale { - /** - * @brief convenience alias for arrays of bytes - */ + + /// @brief convenience alias for arrays of bytes using ByteArray = std::vector; - /** - * @brief represents compact integer value - */ + + /// @brief convenience alias for immutable span of bytes + using ConstSpanOfBytes = std::span; + + /// @brief convenience alias for mutable span of bytes + using MutSpanOfBytes = std::span; + + /// @brief represents compact integer value using CompactInteger = boost::multiprecision::cpp_int; - /** - * @brief OptionalBool is internal extended bool type - */ - enum class OptionalBool : uint8_t { NONE = 0u, OPT_TRUE = 1u, OPT_FALSE = 2u }; + /// @brief OptionalBool is internal extended bool type + enum class OptionalBool : uint8_t { + NONE = 0u, + OPT_TRUE = 1u, + OPT_FALSE = 2u, + }; + + template + concept RangeOfBytes = + std::ranges::sized_range and std::ranges::contiguous_range + and std::is_same_v>, uint8_t>; + } // namespace scale namespace scale::compact { + /** * @brief categories of compact encoding */ @@ -40,5 +56,6 @@ namespace scale::compact { // min integer encoded as multibyte constexpr static size_t kMinBigInteger = (1ul << 30u); }; + } // namespace scale::compact #endif // SCALE_SCALE_TYPES_HPP diff --git a/include/scale/unreachable.hpp b/include/scale/unreachable.hpp index 456aef3..c2741c0 100644 --- a/include/scale/unreachable.hpp +++ b/include/scale/unreachable.hpp @@ -24,4 +24,4 @@ class Unreachable_At_Line {}; #undef GCC_VERSION -#endif // SCALE_UNREACHABLE_HPP +#endif // SCALE_UNREACHABLE_HPP diff --git a/include/scale/visitor.hpp b/include/scale/visitor.hpp index 13364cc..df78a1e 100644 --- a/include/scale/visitor.hpp +++ b/include/scale/visitor.hpp @@ -58,7 +58,7 @@ namespace scale { * @return visitor */ template - constexpr auto make_visitor(Fs &&... fs) { + constexpr auto make_visitor(Fs &&...fs) { using visitor_type = lambda_visitor...>; return visitor_type(std::forward(fs)...); } @@ -80,7 +80,7 @@ namespace scale { */ template constexpr decltype(auto) visit_in_place(TVariant &&variant, - TVisitors &&... visitors) { + TVisitors &&...visitors) { return boost::apply_visitor( make_visitor(std::forward(visitors)...), std::forward(variant)); @@ -95,7 +95,7 @@ namespace scale { /// construct visitor from Fs and apply it to optional T template - constexpr decltype(auto) match_in_place(T &&t, Fs &&... fs) { + constexpr decltype(auto) match_in_place(T &&t, Fs &&...fs) { return match(std::forward(t), make_visitor(std::forward(fs)...)); } } // namespace scale diff --git a/src/buffer/buffer.cpp b/src/buffer/buffer.cpp index 273b0ff..6e92673 100644 --- a/src/buffer/buffer.cpp +++ b/src/buffer/buffer.cpp @@ -43,14 +43,15 @@ namespace scale { } std::string_view Buffer::toString() const { - return std::string_view(reinterpret_cast(data_.data()), data_.size()); // NOLINT + return {reinterpret_cast(data_.data()), // NOLINT + data_.size()}; } bool Buffer::empty() const { return data_.empty(); } - Buffer::Buffer(std::initializer_list b) : data_(b) {} + Buffer::Buffer(std::initializer_list il) : data_(il) {} Buffer::iterator Buffer::begin() { return data_.begin(); @@ -78,17 +79,14 @@ namespace scale { return Buffer{std::move(bytes)}; } - Buffer::Buffer(std::vector v) : data_(std::move(v)) {} - Buffer::Buffer(gsl::span s) : data_(s.begin(), s.end()) {} + Buffer::Buffer(std::vector vector) : data_(std::move(vector)) {} + Buffer::Buffer(const RangeOfBytes auto &range) + : data_(range.begin(), range.end()) {} const std::vector &Buffer::toVector() const { return data_; } - bool Buffer::operator==(const Buffer &b) const noexcept { - return data_ == b.data_; - } - Buffer::const_iterator Buffer::begin() const { return data_.begin(); } @@ -107,16 +105,13 @@ namespace scale { Buffer::Buffer(size_t size, uint8_t byte) : data_(size, byte) {} - bool Buffer::operator==(const std::vector &b) const noexcept { - return data_ == b; - } - - bool Buffer::operator==(gsl::span s) const noexcept { - return std::equal(data_.begin(), data_.end(), s.begin(), s.end()); + bool Buffer::operator==(const RangeOfBytes auto &other) const noexcept { + return std::equal(data_.begin(), data_.end(), other.begin(), other.end()); } - bool Buffer::operator<(const Buffer &b) const noexcept { - return std::lexicographical_compare(begin(), end(), b.begin(), b.end()); + bool Buffer::operator<(const RangeOfBytes auto &other) const noexcept { + return std::lexicographical_compare( + begin(), end(), other.begin(), other.end()); } template @@ -126,16 +121,8 @@ namespace scale { return *this; } - Buffer &Buffer::put(std::string_view s) { - return putRange(s.begin(), s.end()); - } - - Buffer &Buffer::put(const std::vector &v) { - return putRange(v.begin(), v.end()); - } - - Buffer &Buffer::put(gsl::span s) { - return putRange(s.begin(), s.end()); + Buffer &Buffer::put(const RangeOfBytes auto &range) { + return putRange(range.begin(), range.end()); } Buffer &Buffer::putBytes(const uint8_t *begin, const uint8_t *end) { @@ -176,15 +163,15 @@ namespace scale { } Buffer Buffer::subbuffer(size_t offset, size_t length) const { - return Buffer(gsl::make_span(*this).subspan(offset, length)); + return Buffer(ConstSpanOfBytes(*this).subspan(offset, length)); } Buffer &Buffer::operator+=(const Buffer &other) noexcept { - return this->putBuffer(other); + return this->put(other); } std::ostream &operator<<(std::ostream &os, const Buffer &buffer) { return os << buffer.toHex(); } -} // namespace scale::common +} // namespace scale diff --git a/src/buffer/hexutil.cpp b/src/buffer/hexutil.cpp index 4d5dfc4..c59aadb 100644 --- a/src/buffer/hexutil.cpp +++ b/src/buffer/hexutil.cpp @@ -6,7 +6,7 @@ #include "scale/buffer/hexutil.hpp" -#include +#include #include @@ -45,25 +45,20 @@ namespace scale { return str; } - std::string hex_upper(const gsl::span bytes) noexcept { + std::string hex_upper(const RangeOfBytes auto &bytes) noexcept { std::string res(bytes.size() * 2, '\x00'); boost::algorithm::hex(bytes.begin(), bytes.end(), res.begin()); return res; } - std::string hex_lower(const gsl::span bytes) noexcept { - std::string res(bytes.size() * 2, '\x00'); - boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); - return res; - } - - std::string hex_lower_0x(gsl::span bytes) noexcept { + std::string hex_lower_0x(const RangeOfBytes auto &bytes) noexcept { constexpr size_t prefix_len = sizeof("0x") - 1; std::string res(bytes.size() * 2 + prefix_len, '\x00'); res.replace(0, prefix_len, "0x", prefix_len); - boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin() + prefix_len); + boost::algorithm::hex_lower( + bytes.begin(), bytes.end(), res.begin() + prefix_len); return res; } diff --git a/src/compact_len_utils.hpp b/src/compact_len_utils.hpp index 0d9d51a..a7f75ce 100644 --- a/src/compact_len_utils.hpp +++ b/src/compact_len_utils.hpp @@ -15,7 +15,7 @@ namespace scale::compact { size_t counter = 0; do { ++counter; - } while((v >>= 8) != 0); + } while ((v >>= 8) != 0); return counter; } diff --git a/src/encode_append.cpp b/src/encode_append.cpp index 1cd3b3a..2e02591 100644 --- a/src/encode_append.cpp +++ b/src/encode_append.cpp @@ -29,7 +29,7 @@ namespace scale { } outcome::result append_or_new_vec(std::vector &self_encoded, - gsl::span input) { + ConstSpanOfBytes input) { EncodeOpaqueValue opaque_value{.v = input}; // No data present, just encode the given input data. diff --git a/src/scale_decoder_stream.cpp b/src/scale_decoder_stream.cpp index 483096f..fbaa5fe 100644 --- a/src/scale_decoder_stream.cpp +++ b/src/scale_decoder_stream.cpp @@ -6,8 +6,6 @@ #include "scale/scale_decoder_stream.hpp" -#include - #include "scale/scale_error.hpp" #include "scale/types.hpp" @@ -78,9 +76,6 @@ namespace scale { } } // namespace - ScaleDecoderStream::ScaleDecoderStream(gsl::span span) - : span_{span}, current_iterator_{span_.begin()}, current_index_{0} {} - std::optional ScaleDecoderStream::decodeOptionalBool() { auto byte = nextByte(); switch (static_cast(byte)) { diff --git a/src/scale_error.cpp b/src/scale_error.cpp index 0e70e62..aa8ae9d 100644 --- a/src/scale_error.cpp +++ b/src/scale_error.cpp @@ -27,8 +27,8 @@ OUTCOME_CPP_DEFINE_CATEGORY_3(scale, DecodeError, e) { case DecodeError::UNEXPECTED_VALUE: return "SCALE decode: unexpected value occurred"; case DecodeError::TOO_MANY_ITEMS: - return "SCALE decode: collection has too many items or memory is out or data is " - "damaged, unable to unpack"; + return "SCALE decode: collection has too many items or memory is out or " + "data is damaged, unable to unpack"; case DecodeError::WRONG_TYPE_INDEX: return "SCALE decode: wrong type index, cannot decode variant"; case DecodeError::INVALID_ENUM_VALUE: diff --git a/test/scale_boolean_test.cpp b/test/scale_boolean_test.cpp index 5b031be..c911caa 100644 --- a/test/scale_boolean_test.cpp +++ b/test/scale_boolean_test.cpp @@ -47,13 +47,11 @@ struct ThreeBooleans { bool b3 = false; }; -template > - Stream &operator>>(Stream &s, ThreeBooleans &v) { +template > +Stream &operator>>(Stream &s, ThreeBooleans &v) { return s >> v.b1 >> v.b2 >> v.b3; } - /** * @given byte array containing values {0, 1, 2} * @when scale::decode function is applied sequentially diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index 66477b8..af68bfd 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -46,7 +46,7 @@ TEST(Scale, encodeVectorOfBool) { ASSERT_NO_THROW((s << collection)); auto &&out = s.to_vector(); - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); std::vector decoded; stream >> decoded; ASSERT_TRUE(std::equal( @@ -84,7 +84,7 @@ TEST(Scale, encodeCollectionUint16) { ASSERT_NO_THROW((s << collection)); auto &&out = s.to_vector(); - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); std::vector decoded; stream >> decoded; ASSERT_TRUE(std::equal( @@ -121,7 +121,7 @@ TEST(Scale, encodeDerivedCollectionUint16) { ASSERT_NO_THROW((s << collection)); auto &&out = s.to_vector(); - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); TestStruct decoded; stream >> decoded; ASSERT_TRUE(std::equal( @@ -150,7 +150,7 @@ TEST(Scale, encodeDequeUint16) { ASSERT_NO_THROW((s << collection)); auto &&out = s.to_vector(); - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); std::deque decoded; stream >> decoded; ASSERT_TRUE(std::equal( @@ -237,7 +237,7 @@ TEST(Scale, encodeLongCollectionUint16) { // header takes 4 byte, // first 4 bytes represent le-encoded value 2^16 + 2 // which is compact-encoded value 2^14 = 16384 - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); CompactInteger res{}; ASSERT_NO_THROW(stream >> res); ASSERT_EQ(res, 16384); @@ -285,7 +285,7 @@ TEST(Scale, encodeVeryLongCollectionUint8) { // which means that number of items requires 4 bytes // 3 next bytes are 0, and the last 4-th == 2^6 == 64 // which is compact-encoded value 2^14 = 16384 - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); CompactInteger bi{}; ASSERT_NO_THROW(stream >> bi); ASSERT_EQ(bi, 1048576); @@ -331,7 +331,7 @@ TEST(Scale, DISABLED_encodeVeryLongCollectionUint8) { // requires 4 bytes // 3 next bytes are 0, and the last 4-th == 2^6 == 64 // which is compact-encoded value 2^14 = 16384 - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); CompactInteger bi{}; ASSERT_NO_THROW(stream >> bi); ASSERT_EQ(bi, length); @@ -361,7 +361,7 @@ TEST(Scale, encodeMapTest) { ASSERT_NO_THROW((s << collection)); auto &&out = s.to_vector(); - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); std::map decoded; stream >> decoded; ASSERT_TRUE(std::equal( @@ -401,21 +401,21 @@ TEST(Scale, decodeSizeLimitedCollection) { auto &&out = s.to_vector(); { - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); SizeLimitedVector<4, int> decoded; ASSERT_NO_THROW((stream >> decoded)); ASSERT_TRUE(std::equal( decoded.begin(), decoded.end(), collection.begin(), collection.end())); } { - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); SizeLimitedVector<3, int> decoded; ASSERT_NO_THROW((stream >> decoded)); ASSERT_TRUE(std::equal( decoded.begin(), decoded.end(), collection.begin(), collection.end())); } { - auto stream = ScaleDecoderStream(gsl::make_span(out)); + auto stream = ScaleDecoderStream(out); SizeLimitedVector<2, int> decoded; try { diff --git a/test/scale_compact_test.cpp b/test/scale_compact_test.cpp index dfa6ef6..43776d3 100644 --- a/test/scale_compact_test.cpp +++ b/test/scale_compact_test.cpp @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include @@ -52,7 +54,7 @@ TEST_P(CompactTest, EncodeSuccess) { */ TEST_P(CompactTest, DecodeSuccess) { const auto &[value_match, bytes] = GetParam(); - ScaleDecoderStream s(gsl::make_span(bytes)); + ScaleDecoderStream s(bytes); CompactInteger v{}; ASSERT_NO_THROW(s >> v); ASSERT_EQ(v, value_match); diff --git a/test/scale_convenience_functions_test.cpp b/test/scale_convenience_functions_test.cpp index cdde3ff..5add77e 100644 --- a/test/scale_convenience_functions_test.cpp +++ b/test/scale_convenience_functions_test.cpp @@ -23,13 +23,12 @@ struct TestStruct { }; template > - Stream &operator<<(Stream &s, const TestStruct &test_struct) { +Stream &operator<<(Stream &s, const TestStruct &test_struct) { return s << test_struct.a << test_struct.b; } -template > - Stream &operator>>(Stream &s, TestStruct &test_struct) { +template > +Stream &operator>>(Stream &s, TestStruct &test_struct) { return s >> test_struct.a >> test_struct.b; } diff --git a/test/scale_encode_counter_test.cpp b/test/scale_encode_counter_test.cpp index fd18412..8f134f4 100644 --- a/test/scale_encode_counter_test.cpp +++ b/test/scale_encode_counter_test.cpp @@ -6,10 +6,10 @@ #include -#include #include +#include -#include "scale/scale_encoder_stream.hpp" +#include using scale::ScaleEncoderStream; diff --git a/test/scale_strings_test.cpp b/test/scale_strings_test.cpp index f1b6277..b0f4d36 100644 --- a/test/scale_strings_test.cpp +++ b/test/scale_strings_test.cpp @@ -19,10 +19,10 @@ using scale::ScaleEncoderStream; * @then encoded value meets expectations */ TEST(Scale, RawStringEncodeSuccess) { -auto * v = "asdadad"; -ScaleEncoderStream s{}; -ASSERT_NO_THROW((s << v)); -ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); + auto *v = "asdadad"; + ScaleEncoderStream s{}; + ASSERT_NO_THROW((s << v)); + ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); } /** @@ -31,10 +31,10 @@ ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); * @then encoded value meets expectations */ TEST(Scale, StdStringEncodeSuccess) { -std::string v = "asdadad"; -ScaleEncoderStream s; -ASSERT_NO_THROW((s << v)); -ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); + std::string v = "asdadad"; + ScaleEncoderStream s; + ASSERT_NO_THROW((s << v)); + ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); } /** @@ -43,9 +43,9 @@ ASSERT_EQ(s.to_vector(), (ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'})); * @then decoded string matches expectations */ TEST(Scale, StringDecodeSuccess) { -auto bytes = ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'}; -ScaleDecoderStream s(bytes); -std::string v; -ASSERT_NO_THROW(s >> v); -ASSERT_EQ(v, "asdadad"); + auto bytes = ByteArray{28, 'a', 's', 'd', 'a', 'd', 'a', 'd'}; + ScaleDecoderStream s(bytes); + std::string v; + ASSERT_NO_THROW(s >> v); + ASSERT_EQ(v, "asdadad"); } diff --git a/test/scale_tuple_test.cpp b/test/scale_tuple_test.cpp index df47882..2159bb7 100644 --- a/test/scale_tuple_test.cpp +++ b/test/scale_tuple_test.cpp @@ -58,7 +58,6 @@ TEST(Scale, EncodeDecodeTupleSuccess) { std::make_tuple(uint8_t(1), uint16_t(3), uint8_t(2), uint32_t(4)); EXPECT_OUTCOME_TRUE(actual_bytes, scale::encode(tuple)); - EXPECT_OUTCOME_TRUE(decoded, - scale::decode(actual_bytes)); + EXPECT_OUTCOME_TRUE(decoded, scale::decode(actual_bytes)); ASSERT_EQ(decoded, tuple); } diff --git a/test/scale_variant_test.cpp b/test/scale_variant_test.cpp index f9610de..e54236b 100644 --- a/test/scale_variant_test.cpp +++ b/test/scale_variant_test.cpp @@ -8,7 +8,6 @@ #include "scale/scale.hpp" -#include #include "util/outcome.hpp" using scale::ByteArray; diff --git a/test/util/literals.hpp b/test/util/literals.hpp index 01c3256..7c15505 100644 --- a/test/util/literals.hpp +++ b/test/util/literals.hpp @@ -32,5 +32,4 @@ inline std::vector operator""_unhex(const char *c, size_t s) { return scale::unhex(std::string_view(c, s)).value(); } - #endif // SCAKE_TESTUTIL_LITERALS_HPP diff --git a/test/util/outcome.hpp b/test/util/outcome.hpp index 6d81677..7f52353 100644 --- a/test/util/outcome.hpp +++ b/test/util/outcome.hpp @@ -9,8 +9,8 @@ #include -#include #include +#include #define PP_CAT(a, b) PP_CAT_I(a, b) #define PP_CAT_I(a, b) PP_CAT_II(~, a##b) From b8db9cbe0bf783751c31e37602df410e9ff732bf Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 19:16:06 +0300 Subject: [PATCH 05/19] refactor: replace include-guards by pragma-once --- include/scale/bitvec.hpp | 5 +---- include/scale/buffer/buffer.hpp | 5 +---- include/scale/buffer/hexutil.hpp | 5 +---- include/scale/detail/fixed_width_integer.hpp | 5 +---- include/scale/detail/variant.hpp | 5 +---- include/scale/encode_append.hpp | 5 +---- include/scale/enum_traits.hpp | 5 +---- include/scale/outcome/outcome-register.hpp | 6 +----- include/scale/outcome/outcome.hpp | 5 +---- include/scale/outcome/outcome_throw.hpp | 5 +---- include/scale/scale.hpp | 5 +---- include/scale/scale_decoder_stream.hpp | 5 +---- include/scale/scale_encoder_stream.hpp | 5 +---- include/scale/scale_error.hpp | 5 +---- include/scale/types.hpp | 4 +--- include/scale/unreachable.hpp | 5 +---- include/scale/visitor.hpp | 5 +---- src/compact_len_utils.hpp | 5 +---- test/append_test_data.hpp | 5 +---- test/util/literals.hpp | 5 +---- test/util/outcome.hpp | 5 +---- 21 files changed, 21 insertions(+), 84 deletions(-) diff --git a/include/scale/bitvec.hpp b/include/scale/bitvec.hpp index 1db3154..7e65490 100644 --- a/include/scale/bitvec.hpp +++ b/include/scale/bitvec.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_BITVEC_HPP -#define SCALE_BITVEC_HPP +#pragma once #include @@ -24,5 +23,3 @@ namespace scale { } }; } // namespace scale - -#endif // SCALE_BITVEC_HPP diff --git a/include/scale/buffer/buffer.hpp b/include/scale/buffer/buffer.hpp index eab39f1..2e9df4d 100644 --- a/include/scale/buffer/buffer.hpp +++ b/include/scale/buffer/buffer.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_BUFFER_HPP -#define SCALE_BUFFER_HPP +#pragma once #include #include @@ -257,5 +256,3 @@ namespace std { } }; } // namespace std - -#endif // SCALE_BUFFER_HPP diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp index 5fd3e14..3fbc7b6 100644 --- a/include/scale/buffer/hexutil.hpp +++ b/include/scale/buffer/hexutil.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_HEXUTIL_HPP -#define SCALE_HEXUTIL_HPP +#pragma once #include #include @@ -114,5 +113,3 @@ namespace scale { } // namespace scale OUTCOME_HPP_DECLARE_ERROR_2(scale, UnhexError) - -#endif // SCALE_HEXUTIL_HPP diff --git a/include/scale/detail/fixed_width_integer.hpp b/include/scale/detail/fixed_width_integer.hpp index 5439fbe..b0c0201 100644 --- a/include/scale/detail/fixed_width_integer.hpp +++ b/include/scale/detail/fixed_width_integer.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_SCALE_UTIL_HPP -#define SCALE_SCALE_UTIL_HPP +#pragma once #include #include @@ -103,5 +102,3 @@ namespace scale::detail { return sv; } } // namespace scale::detail - -#endif // SCALE_SCALE_UTIL_HPP diff --git a/include/scale/detail/variant.hpp b/include/scale/detail/variant.hpp index 9a13e7d..c65ed86 100644 --- a/include/scale/detail/variant.hpp +++ b/include/scale/detail/variant.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_SCALE_DETAIL_VARIANT_HPP -#define SCALE_SCALE_DETAIL_VARIANT_HPP +#pragma once #include @@ -117,5 +116,3 @@ namespace scale::detail { } } // namespace scale::detail - -#endif // SCALE_SCALE_DETAIL_VARIANT_HPP diff --git a/include/scale/encode_append.hpp b/include/scale/encode_append.hpp index 31f7508..e177b8a 100644 --- a/include/scale/encode_append.hpp +++ b/include/scale/encode_append.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_CORE_SCALE_ENCODE_APPEND_HPP -#define SCALE_CORE_SCALE_ENCODE_APPEND_HPP +#pragma once #include @@ -51,5 +50,3 @@ namespace scale { return append_or_new_vec(self_encoded, ConstSpanOfBytes(input)); } } // namespace scale - -#endif // SCALE_CORE_SCALE_ENCODE_APPEND_HPP diff --git a/include/scale/enum_traits.hpp b/include/scale/enum_traits.hpp index 7203e7a..fb2f1b8 100644 --- a/include/scale/enum_traits.hpp +++ b/include/scale/enum_traits.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_ENUM_TRAITS_HPP -#define SCALE_ENUM_TRAITS_HPP +#pragma once #include @@ -101,5 +100,3 @@ namespace scale { } } // namespace scale - -#endif // SCALE_ENUM_TRAITS_HPP diff --git a/include/scale/outcome/outcome-register.hpp b/include/scale/outcome/outcome-register.hpp index 4960fea..214c10e 100644 --- a/include/scale/outcome/outcome-register.hpp +++ b/include/scale/outcome/outcome-register.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_OUTCOME_REGISTER_HPP -#define SCALE_OUTCOME_REGISTER_HPP +#pragma once #include #include // bring in std::error_code et al @@ -119,6 +118,3 @@ namespace scale::__outcome_detail { /// with 1 arg : OUTCOME_CPP_DEFINE_CATEGORY_1 #define OUTCOME_HPP_DECLARE_ERROR(...) \ OUTCOME_HPP_DECLARE_ERROR_2(__VA_ARGS__) - - -#endif // SCALE_OUTCOME_REGISTER_HPP diff --git a/include/scale/outcome/outcome.hpp b/include/scale/outcome/outcome.hpp index 56c0dbb..299ab57 100644 --- a/include/scale/outcome/outcome.hpp +++ b/include/scale/outcome/outcome.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_OUTCOME_OUTCOME -#define SCALE_OUTCOME_OUTCOME +#pragma once #pragma warning(push) #pragma warning(disable : 4583) @@ -36,5 +35,3 @@ namespace scale::outcome { #define GET_MACRO(_1, _2, NAME, ...) NAME #define OUTCOME_TRY(...) \ GET_MACRO(__VA_ARGS__, OUTCOME_TRY_2, OUTCOME_TRY_1)(__VA_ARGS__) - -#endif // SCALE_OUTCOME_OUTCOME diff --git a/include/scale/outcome/outcome_throw.hpp b/include/scale/outcome/outcome_throw.hpp index 5e00777..9b876fd 100644 --- a/include/scale/outcome/outcome_throw.hpp +++ b/include/scale/outcome/outcome_throw.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_COMMON_OUTCOME_THROW_HPP -#define SCALE_COMMON_OUTCOME_THROW_HPP +#pragma once #include #include @@ -32,5 +31,3 @@ namespace scale { boost::throw_exception(std::system_error(t.value(), t.category())); } } // namespace scale - -#endif // SCALE_COMMON_OUTCOME_THROW_HPP diff --git a/include/scale/scale.hpp b/include/scale/scale.hpp index 9ccedf0..53923d4 100644 --- a/include/scale/scale.hpp +++ b/include/scale/scale.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_SCALE_HPP -#define SCALE_SCALE_HPP +#pragma once #include @@ -72,5 +71,3 @@ namespace scale { return outcome::success(std::move(t)); } } // namespace scale - -#endif // SCALE_SCALE_HPP diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index 6023d50..2f994e7 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_CORE_SCALE_SCALE_DECODER_STREAM_HPP -#define SCALE_CORE_SCALE_SCALE_DECODER_STREAM_HPP +#pragma once #include #include @@ -454,5 +453,3 @@ namespace scale { }; } // namespace scale - -#endif // SCALE_CORE_SCALE_SCALE_DECODER_STREAM_HPP diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index 7b7380f..eb7b4b5 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_CORE_SCALE_SCALE_ENCODER_STREAM_HPP -#define SCALE_CORE_SCALE_SCALE_ENCODER_STREAM_HPP +#pragma once #include #include @@ -397,5 +396,3 @@ namespace scale { } } // namespace scale - -#endif // SCALE_CORE_SCALE_SCALE_ENCODER_STREAM_HPP diff --git a/include/scale/scale_error.hpp b/include/scale/scale_error.hpp index 3d36b13..65a7a1d 100644 --- a/include/scale/scale_error.hpp +++ b/include/scale/scale_error.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_SCALE_ERROR_HPP -#define SCALE_SCALE_ERROR_HPP +#pragma once #include @@ -37,5 +36,3 @@ namespace scale { OUTCOME_HPP_DECLARE_ERROR_2(scale, EncodeError) OUTCOME_HPP_DECLARE_ERROR_2(scale, DecodeError) - -#endif // SCALE_SCALE_ERROR_HPP diff --git a/include/scale/types.hpp b/include/scale/types.hpp index 013eafd..4f2ddce 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_SCALE_TYPES_HPP -#define SCALE_SCALE_TYPES_HPP +#pragma once #include #include @@ -58,4 +57,3 @@ namespace scale::compact { }; } // namespace scale::compact -#endif // SCALE_SCALE_TYPES_HPP diff --git a/include/scale/unreachable.hpp b/include/scale/unreachable.hpp index c2741c0..bd5e6fc 100644 --- a/include/scale/unreachable.hpp +++ b/include/scale/unreachable.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_UNREACHABLE_HPP -#define SCALE_UNREACHABLE_HPP +#pragma once /** * @brief This file declares UNREACHABLE macro. Use it to prevent compiler @@ -23,5 +22,3 @@ class Unreachable_At_Line {}; #endif #undef GCC_VERSION - -#endif // SCALE_UNREACHABLE_HPP diff --git a/include/scale/visitor.hpp b/include/scale/visitor.hpp index df78a1e..d43e779 100644 --- a/include/scale/visitor.hpp +++ b/include/scale/visitor.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_VISITOR_HPP -#define SCALE_VISITOR_HPP +#pragma once #include // for std::decay #include // for std::forward @@ -99,5 +98,3 @@ namespace scale { return match(std::forward(t), make_visitor(std::forward(fs)...)); } } // namespace scale - -#endif // SCALE_VISITOR_HPP diff --git a/src/compact_len_utils.hpp b/src/compact_len_utils.hpp index a7f75ce..cecef40 100644 --- a/src/compact_len_utils.hpp +++ b/src/compact_len_utils.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_CORE_SCALE_COMPACT_LEN_UTILS_HPP -#define SCALE_CORE_SCALE_COMPACT_LEN_UTILS_HPP +#pragma once #include "scale/types.hpp" @@ -32,5 +31,3 @@ namespace scale::compact { return countBytes(val); } } // namespace scale::compact - -#endif // SCALE_CORE_SCALE_COMPACT_LEN_UTILS_HPP diff --git a/test/append_test_data.hpp b/test/append_test_data.hpp index bb91886..365c094 100644 --- a/test/append_test_data.hpp +++ b/test/append_test_data.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_APPEND_TEST_DATA_HPP -#define SCALE_APPEND_TEST_DATA_HPP +#pragma once namespace data { constexpr auto append_bytes = @@ -15786,5 +15785,3 @@ namespace data { "000000"); } // namespace data - -#endif // SCALE_APPEND_TEST_DATA_HPP diff --git a/test/util/literals.hpp b/test/util/literals.hpp index 7c15505..2d6847b 100644 --- a/test/util/literals.hpp +++ b/test/util/literals.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_TESTUTIL_LITERALS_HPP -#define SCALE_TESTUTIL_LITERALS_HPP +#pragma once #include #include @@ -31,5 +30,3 @@ inline std::vector operator""_unhex(const char *c, size_t s) { return scale::unhexWith0x(std::string_view(c, s)).value(); return scale::unhex(std::string_view(c, s)).value(); } - -#endif // SCAKE_TESTUTIL_LITERALS_HPP diff --git a/test/util/outcome.hpp b/test/util/outcome.hpp index 7f52353..593ce6b 100644 --- a/test/util/outcome.hpp +++ b/test/util/outcome.hpp @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SCALE_GTEST_OUTCOME_UTIL_HPP -#define SCALE_GTEST_OUTCOME_UTIL_HPP +#pragma once #include @@ -204,5 +203,3 @@ << "Expected: Error '" \ << outcome::result(_error_).error().message() << "'"; \ } - -#endif // SCALE_GTEST_OUTCOME_UTIL_HPP From 3dd723b512160d609bf0d8e4ef966c577ded2c64 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Tue, 24 Oct 2023 00:20:38 +0300 Subject: [PATCH 06/19] feature: concepts for static and dynamic collections --- include/scale/scale_decoder_stream.hpp | 186 +++++++------------------ include/scale/scale_encoder_stream.hpp | 130 +++-------------- include/scale/types.hpp | 68 +++++++++ src/scale_decoder_stream.cpp | 8 -- test/scale_collection_test.cpp | 84 +++++++++++ 5 files changed, 228 insertions(+), 248 deletions(-) diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index 2f994e7..f3d21d1 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -174,92 +174,43 @@ namespace scale { ScaleDecoderStream &operator>>(CompactInteger &v); /** - * @brief decodes custom container with is_static_collection bool class - * member - * @tparam C container type - * @param c reference to container + * @brief scale-decodes to any static (fixed-size) collection + * @param collection decoding collection to * @return reference to stream */ - template > - ScaleDecoderStream &operator>>(C &c) { - using mutableT = std::remove_const_t; - using size_type = S; - - static_assert(std::is_default_constructible_v); - - if constexpr (C::is_static_collection) { - C container; - for (auto &el : container) { - *this >> el; - } - - c = std::move(container); - return *this; - } else { - return decodeVectorLike(c); + ScaleDecoderStream &operator>>(StaticCollection auto &container) { + for (auto &item : container) { + *this >> item; } + return *this; } /** - * @brief decodes vector - * @tparam T item type - * @param v reference to container - * @return reference to stream - */ - template - ScaleDecoderStream &operator>>(std::vector &v) { - return decodeVectorLike(v); - } - /** - * @brief decodes deque - * @tparam T item type - * @param v reference to container - * @return reference to stream - */ - template - ScaleDecoderStream &operator>>(std::deque &v) { - return decodeVectorLike(v); - } - - /** - * @brief decodes random access resizable container - * @tparam T item type - * @param v reference to container + * @brief scale-decodes to resizeable collection (which can be resized first + * and rewrite elements while decoding) + * @param collection decoding collection to * @return reference to stream */ - template - ScaleDecoderStream &decodeVectorLike(C &v) { - using mutableT = std::remove_const_t; - using size_type = S; - - static_assert(std::is_default_constructible_v); + ScaleDecoderStream &operator>>(ResizeableCollection auto &collection) { + using size_type = decltype(collection.size()); CompactInteger size{0u}; *this >> size; auto item_count = size.convert_to(); - if (item_count > v.max_size()) { + if (item_count > collection.max_size()) { raise(DecodeError::TOO_MANY_ITEMS); } - C container; try { - container.resize(item_count); + collection.resize(item_count); } catch (const std::bad_alloc &) { raise(DecodeError::TOO_MANY_ITEMS); } - for (size_type i = 0u; i < item_count; ++i) { - *this >> container[i]; + for (auto &item : collection) { + *this >> item; } - - v = std::move(container); return *this; } @@ -268,23 +219,27 @@ namespace scale { * @param v reference to container * @return reference to stream */ - ScaleDecoderStream &operator>>(std::vector &v) { + ScaleDecoderStream &operator>>(std::vector &collection) { CompactInteger size{0u}; *this >> size; auto item_count = size.convert_to(); - if (item_count > v.max_size()) { + if (item_count > collection.max_size()) { + raise(DecodeError::TOO_MANY_ITEMS); + } + + try { + collection.resize(item_count); + } catch (const std::bad_alloc &) { raise(DecodeError::TOO_MANY_ITEMS); } - std::vector container; - bool el; + bool item; for (size_t i = 0u; i < item_count; ++i) { - *this >> el; - container.push_back(el); + *this >> item; + collection[i] = item; } - v = std::move(container); return *this; } @@ -294,102 +249,69 @@ namespace scale { ScaleDecoderStream &operator>>(BitVec &v); /** - * @brief decodes list of items - * @tparam T item type - * @param v reference to collection + * @brief scale-decodes to sequential collection (which can be reserved + * space first and push element by element back while decoding) * @return reference to stream */ template - ScaleDecoderStream &operator>>(std::list &v) { - using mutableT = std::remove_const_t; - using size_type = typename std::list::size_type; - - static_assert(std::is_default_constructible_v); + ScaleDecoderStream &operator>>(SequentialCollection auto &collection) { + using size_type = std::decay_t::size_type; + using value_type = std::decay_t::value_type; CompactInteger size{0u}; *this >> size; auto item_count = size.convert_to(); - if (item_count > v.max_size()) { + if (item_count > collection.max_size()) { raise(DecodeError::TOO_MANY_ITEMS); } - std::list lst; + collection.clear(); try { - lst.reserve(item_count); + collection.reserve(item_count); } catch (const std::bad_alloc &) { raise(DecodeError::TOO_MANY_ITEMS); } for (size_type i = 0u; i < item_count; ++i) { - lst.emplace_back(); - *this >> lst.back(); + collection.emplace_back(); + *this >> collection.back(); } - v = std::move(lst); return *this; } - template - struct is_map_like : std::false_type {}; - - template - struct is_map_like()[std::declval< - const typename T::key_type &>()])>> - : std::true_type {}; - /** - * @brief decodes associative containers - * @tparam C item type - * @param c reference to the map + * @brief scale-decodes to non-sequential collection (which can not be + * reserved space or resize, but each element can be emplaced while + * decoding) * @return reference to stream */ - template ::value>> - ScaleDecoderStream &operator>>(C &c) { + ScaleDecoderStream &operator>>(NonSequentialCollection auto &collection) { + using size_type = std::decay_t::size_type; + using value_type = std::decay_t::value_type; + CompactInteger size{0u}; *this >> size; - auto item_count = size.convert_to(); - if (item_count > c.max_size()) { + auto item_count = size.convert_to(); + if (item_count > collection.max_size()) { raise(DecodeError::TOO_MANY_ITEMS); } - C container; - typename C::value_type pair; - for (size_t i = 0u; i < item_count; ++i) { - *this >> pair; - container.emplace(pair); - } + value_type item; - c = std::move(container); - return *this; - } - - /** - * @brief decodes array of items - * @tparam T item type - * @tparam size of the array - * @param a reference to the array - * @return reference to stream - */ - template - ScaleDecoderStream &operator>>(std::array &a) { - using mutableT = std::remove_const_t; - for (size_t i = 0u; i < size; ++i) { - *this >> const_cast(a[i]); // NOLINT + collection.clear(); + for (size_type i = 0u; i < item_count; ++i) { + *this >> item; + try { + collection.emplace(std::move(item)); + } catch (const std::bad_alloc &) { + raise(DecodeError::TOO_MANY_ITEMS); + } } return *this; } - /** - * @brief decodes string from stream - * @param v value to decode - * @return reference to stream - */ - ScaleDecoderStream &operator>>(std::string &v); - /** * @brief hasMore Checks whether n more bytes are available * @param n Number of bytes to check diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index eb7b4b5..4a1afbf 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -46,48 +46,6 @@ namespace scale { */ size_t size() const; - /** - * @brief scale-encodes std::vector - * @tparam T type of item - * @param c collection to encode - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::vector &c) { - return encodeDynamicCollection(std::size(c), std::begin(c), std::end(c)); - } - /** - * @brief scale-encodes std::deque - * @tparam T type of item - * @param c collection to encode - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::deque &c) { - return encodeDynamicCollection(std::size(c), std::begin(c), std::end(c)); - } - /** - * @brief scale-encodes std::list - * @tparam T type of item - * @param c collection to encode - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::list &c) { - return encodeDynamicCollection(std::size(c), std::begin(c), std::end(c)); - } - /** - * @brief scale-encodes std::map - * @tparam K key type - * @tparam V mapped type - * @param c collection to encode - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::map &c) { - return encodeDynamicCollection(std::size(c), std::begin(c), std::end(c)); - } - /** * @brief scale-encodes span * @tparam T type of item @@ -95,53 +53,28 @@ namespace scale { * @param span span to encode * @return reference to stream */ - template + template ScaleEncoderStream &operator<<(const std::span &span) { if constexpr (S == -1) { return encodeDynamicCollection( - std::size(span), std::begin(span), std::end(span)); + ExplicitlyDynamic>(span)); } else { - return encodeStaticCollection(span); + return encodeStaticCollection( // + ExplicitlyStatic>(span)); } } /** * @brief scale-encodes range - * @param range range to encode + * @param collection range to encode * @return reference to stream */ - ScaleEncoderStream &operator<<(std::ranges::range auto range) { - return encodeDynamicCollection( - std::size(range), std::begin(range), std::end(range)); + ScaleEncoderStream &operator<<(const DynamicCollection auto &collection) { + return encodeDynamicCollection(collection); } - // /** - // * @brief scale-encodes collection of same type items, requires bool - // tag - // * is_static_collection - // * @tparam C container type, T type of item - // * @param c collection to encode - // * @return reference to stream - // */ - // template > - // ScaleEncoderStream &operator<<(const C &c) { - // if constexpr (C::is_static_collection) { - // return encodeStaticCollection(c); - // } else { - // return encodeDynamicCollection( - // std::size(c), std::begin(c), std::end(c)); - // } - // } - - ScaleEncoderStream &operator<<(const std::vector &v) { - *this << CompactInteger{v.size()}; - for (bool el : v) { - *this << el; - } - return *this; + ScaleEncoderStream &operator<<(const StaticCollection auto &collection) { + return encodeStaticCollection(collection); } /** @@ -244,18 +177,6 @@ namespace scale { return putByte(0u); } - /** - * @brief scale-encodes array of items - * @tparam T item type - * @tparam size of the array - * @param a reference to the array - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::array &a) { - return encodeStaticCollection(a); - } - /** * @brief scale-encodes std::reference_wrapper of a type * @tparam T underlying type @@ -273,7 +194,7 @@ namespace scale { * @return reference to stream */ ScaleEncoderStream &operator<<(std::string_view sv) { - return encodeDynamicCollection(sv.size(), sv.begin(), sv.end()); + return encodeDynamicCollection(ExplicitlyDynamic(sv)); } /** @@ -331,34 +252,27 @@ namespace scale { /** * @brief scale-encodes any dynamic collection - * @tparam It iterator over collection of bytes - * @param size size of the collection - * @param begin iterator pointing to the begin of collection - * @param end iterator pointing to the end of collection + * @param collection encoding collection * @return reference to stream */ - template - ScaleEncoderStream &encodeDynamicCollection(const CompactInteger &size, - It &&begin, - It &&end) { - *this << size; - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - for (auto &&it = begin; it != end; ++it) { - *this << *it; + ScaleEncoderStream &encodeDynamicCollection( + const DynamicCollection auto &collection) { + *this << CompactInteger{collection.size()}; + for (const auto &item : collection) { + *this << item; } return *this; } /** - * @brief scale-encodes any fixed-size collection (std::array) - * @tparam C collection type - * @param c collection + * @brief scale-encodes any static (fixed-size) collection + * @param collection encoding collection * @return reference to stream */ - template - ScaleEncoderStream &encodeStaticCollection(const C &c) { - for (const auto &e : c) { - *this << e; + ScaleEncoderStream &encodeStaticCollection( + const StaticCollection auto &collection) { + for (const auto &item : collection) { + *this << item; } return *this; } diff --git a/include/scale/types.hpp b/include/scale/types.hpp index 4f2ddce..5c34b39 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -40,6 +40,74 @@ namespace scale { std::ranges::sized_range and std::ranges::contiguous_range and std::is_same_v>, uint8_t>; + template + struct ExplicitlyStatic : public T { + static constexpr bool is_static_collection = true; + }; + + template + struct ExplicitlyDynamic : public T { + static constexpr bool is_static_collection = false; + }; + + template + concept ExplicitlyDefinedAsStaticOrDynamic = + requires(T) { T::is_static_collection; }; + + template + concept ExplicitlyDefinedAsStatic = + ExplicitlyDefinedAsStaticOrDynamic and T::is_static_collection; + + template + concept ExplicitlyDefinedAsDynamic = + ExplicitlyDefinedAsStaticOrDynamic and not(T::is_static_collection); + + template + concept HasSomeInsertMethod = + requires(T val) { val.insert(val.end(), *val.begin()); } + or requires(T val) { val.insert_after(val.end(), *val.begin()); }; + + template + concept HasResizeMethod = requires(T val) { val.resize(val.size()); }; + + template + concept HasReserveMethod = requires(T val) { val.reserve(val.size()); }; + + template + concept HasEmplaceMethod = requires(T val) { val.emplace(*val.begin()); }; + + template + concept HasEmplaceBackMethod = requires(T val) { val.emplace(*val.begin()); }; + + template + concept ImplicitlyDefinedAsStatic = not + ExplicitlyDefinedAsStaticOrDynamic and not HasSomeInsertMethod; + + template + concept ImplicitlyDefinedAsDynamic = not + ExplicitlyDefinedAsStaticOrDynamic and HasSomeInsertMethod; + + template + concept StaticCollection = std::ranges::range + and (ExplicitlyDefinedAsStatic + or ImplicitlyDefinedAsStatic); + + template + concept DynamicCollection = std::ranges::sized_range + and (ExplicitlyDefinedAsDynamic + or ImplicitlyDefinedAsDynamic); + + template + concept ResizeableCollection = DynamicCollection and HasResizeMethod; + + template + concept SequentialCollection = + DynamicCollection and HasEmplaceBackMethod; + + template + concept NonSequentialCollection = + DynamicCollection and HasEmplaceMethod; + } // namespace scale namespace scale::compact { diff --git a/src/scale_decoder_stream.cpp b/src/scale_decoder_stream.cpp index fbaa5fe..7a8a612 100644 --- a/src/scale_decoder_stream.cpp +++ b/src/scale_decoder_stream.cpp @@ -124,14 +124,6 @@ namespace scale { return *this; } - ScaleDecoderStream &ScaleDecoderStream::operator>>(std::string &v) { - std::vector collection; - *this >> collection; - v.clear(); - v.append(collection.begin(), collection.end()); - return *this; - } - bool ScaleDecoderStream::hasMore(uint64_t n) const { return static_cast(current_index_ + n) <= span_.size(); } diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index af68bfd..85c40d2 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -105,6 +105,7 @@ TEST(Scale, encodeCollectionUint16) { struct TestStruct : std::vector { static constexpr bool is_static_collection = false; }; + /** * @given collection of items of type uint16_t, derived from std::vector * @when encodeCollection is applied @@ -426,3 +427,86 @@ TEST(Scale, decodeSizeLimitedCollection) { } } } + +struct ExplicitlyDefinedAsStatic : public std::vector { + static constexpr bool is_static_collection = true; + using Collection = std::vector; + using Collection::Collection; +}; + +struct ExplicitlyDefinedAsDynamic : public std::vector { + static constexpr bool is_static_collection = false; + using Collection = std::vector; + using Collection::Collection; +}; + +struct ImplicitlyDefinedAsStatic : public std::array { + // using Collection = std::array; + // using Collection::Collection; +}; + +struct ImplicitlyDefinedAsDynamic : public std::vector { + using Collection = std::vector; + using Collection::Collection; +}; + +TEST(Scale, encodeExplicitlyDefinedAsStatic) { + using TestCollection = ExplicitlyDefinedAsStatic; + + const TestCollection collection{1, 2, 3, 4, 5}; + + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + TestCollection decoded{0xff, 0xff, 0xff, 0xff, 0xff}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} + +TEST(Scale, encodeExplicitlyDefinedAsDynamic) { + using TestCollection = ExplicitlyDefinedAsDynamic; + + const TestCollection collection{1, 2, 3, 4, 5}; + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + TestCollection decoded{0xff, 0xff, 0xff}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} + +TEST(Scale, encodeImplicitlyDefinedAsStatic) { + using TestCollection = ImplicitlyDefinedAsStatic; + + const TestCollection collection{1, 2, 3, 4, 5}; + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + TestCollection decoded{0xff, 0xff, 0xff, 0xff, 0xff}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} + +TEST(Scale, encodeImplicitlyDefinedAsDynamic) { + using TestCollection = ImplicitlyDefinedAsDynamic; + + const TestCollection collection{1, 2, 3, 4, 5}; + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + TestCollection decoded{0xff, 0xff, 0xff}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} From 6a4feb226c40eddfd1dfb0e264a3d3e71937d7b4 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Tue, 24 Oct 2023 21:38:52 +0300 Subject: [PATCH 07/19] feature: concepts for static and dynamic span --- include/scale/scale_decoder_stream.hpp | 24 +++++++- include/scale/scale_encoder_stream.hpp | 18 ------ include/scale/types.hpp | 77 +++++++++++++++++------- test/scale_collection_test.cpp | 83 ++++++++++++++++++++------ 4 files changed, 139 insertions(+), 63 deletions(-) diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index f3d21d1..27ed4e3 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -248,13 +248,30 @@ namespace scale { */ ScaleDecoderStream &operator>>(BitVec &v); + ScaleDecoderStream &operator>>(DynamicSpan auto &collection) { + using size_type = std::decay_t::size_type; + using value_type = std::decay_t::value_type; + + CompactInteger size{0u}; + *this >> size; + + auto item_count = size.convert_to(); + if (item_count > collection.size()) { + raise(DecodeError::TOO_MANY_ITEMS); + } + + for (auto &item : collection) { + *this >> item; + } + return *this; + } + /** * @brief scale-decodes to sequential collection (which can be reserved * space first and push element by element back while decoding) * @return reference to stream */ - template - ScaleDecoderStream &operator>>(SequentialCollection auto &collection) { + ScaleDecoderStream &operator>>(ExtensibleBackCollection auto &collection) { using size_type = std::decay_t::size_type; using value_type = std::decay_t::value_type; @@ -286,7 +303,8 @@ namespace scale { * decoding) * @return reference to stream */ - ScaleDecoderStream &operator>>(NonSequentialCollection auto &collection) { + ScaleDecoderStream &operator>>( + RandomExtensibleCollection auto &collection) { using size_type = std::decay_t::size_type; using value_type = std::decay_t::value_type; diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index 4a1afbf..6223f80 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -46,24 +46,6 @@ namespace scale { */ size_t size() const; - /** - * @brief scale-encodes span - * @tparam T type of item - * @tparam S container size (-1 for dynamic) - * @param span span to encode - * @return reference to stream - */ - template - ScaleEncoderStream &operator<<(const std::span &span) { - if constexpr (S == -1) { - return encodeDynamicCollection( - ExplicitlyDynamic>(span)); - } else { - return encodeStaticCollection( // - ExplicitlyStatic>(span)); - } - } - /** * @brief scale-encodes range * @param collection range to encode diff --git a/include/scale/types.hpp b/include/scale/types.hpp index 5c34b39..127654a 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -54,59 +54,90 @@ namespace scale { concept ExplicitlyDefinedAsStaticOrDynamic = requires(T) { T::is_static_collection; }; + template + struct __is_derived_of_span_impl { + template + static constexpr std::true_type test(const std::span *); + static constexpr std::false_type test(...); + using type = decltype(test(std::declval())); + }; + + template + using __is_derived_of_span = typename __is_derived_of_span_impl::type; + + template + concept SomeSpan = __is_derived_of_span::value // + and requires(T) { T::extent; }; + template - concept ExplicitlyDefinedAsStatic = - ExplicitlyDefinedAsStaticOrDynamic and T::is_static_collection; + concept ExplicitlyDefinedAsStatic = ExplicitlyDefinedAsStaticOrDynamic // + and T::is_static_collection; template - concept ExplicitlyDefinedAsDynamic = - ExplicitlyDefinedAsStaticOrDynamic and not(T::is_static_collection); + concept ExplicitlyDefinedAsDynamic = ExplicitlyDefinedAsStaticOrDynamic // + and not(T::is_static_collection); template concept HasSomeInsertMethod = - requires(T val) { val.insert(val.end(), *val.begin()); } - or requires(T val) { val.insert_after(val.end(), *val.begin()); }; + requires(T v) { v.insert(v.end(), *v.begin()); } + or requires(T v) { v.insert_after(v.end(), *v.begin()); }; template - concept HasResizeMethod = requires(T val) { val.resize(val.size()); }; + concept HasResizeMethod = requires(T v) { v.resize(v.size()); }; template - concept HasReserveMethod = requires(T val) { val.reserve(val.size()); }; + concept HasReserveMethod = requires(T v) { v.reserve(v.size()); }; template - concept HasEmplaceMethod = requires(T val) { val.emplace(*val.begin()); }; + concept HasEmplaceMethod = requires(T v) { v.emplace(*v.begin()); }; template - concept HasEmplaceBackMethod = requires(T val) { val.emplace(*val.begin()); }; + concept HasEmplaceBackMethod = requires(T v) { v.emplace_back(*v.begin()); }; template - concept ImplicitlyDefinedAsStatic = not - ExplicitlyDefinedAsStaticOrDynamic and not HasSomeInsertMethod; + concept ImplicitlyDefinedAsStatic = + not(ExplicitlyDefinedAsStaticOrDynamic) and // + not(SomeSpan) and // + not(HasSomeInsertMethod); template - concept ImplicitlyDefinedAsDynamic = not - ExplicitlyDefinedAsStaticOrDynamic and HasSomeInsertMethod; + concept ImplicitlyDefinedAsDynamic = + not(ExplicitlyDefinedAsStaticOrDynamic) and // + not(SomeSpan) and // + HasSomeInsertMethod; + + template + concept StaticSpan = SomeSpan // + and (T::extent != std::dynamic_extent); + + template + concept DynamicSpan = SomeSpan // + and (T::extent == std::dynamic_extent); template concept StaticCollection = std::ranges::range - and (ExplicitlyDefinedAsStatic - or ImplicitlyDefinedAsStatic); + and (ExplicitlyDefinedAsStatic // + or ImplicitlyDefinedAsStatic // + or StaticSpan); template concept DynamicCollection = std::ranges::sized_range - and (ExplicitlyDefinedAsDynamic - or ImplicitlyDefinedAsDynamic); + and (ExplicitlyDefinedAsDynamic // + or ImplicitlyDefinedAsDynamic // + or DynamicSpan); template - concept ResizeableCollection = DynamicCollection and HasResizeMethod; + concept ResizeableCollection = DynamicCollection // + and HasResizeMethod; template - concept SequentialCollection = - DynamicCollection and HasEmplaceBackMethod; + concept ExtensibleBackCollection = DynamicCollection // + and not(HasResizeMethod) // + and HasEmplaceBackMethod; template - concept NonSequentialCollection = - DynamicCollection and HasEmplaceMethod; + concept RandomExtensibleCollection = DynamicCollection // + and HasEmplaceMethod; } // namespace scale diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index 85c40d2..0693fa7 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -306,9 +306,9 @@ TEST(Scale, encodeVeryLongCollectionUint8) { // following test takes too much time, don't run it /** - * @given very long collection of items of type uint8_t containing 2^30 == - * 1073741824 items this number takes ~ 1 Gb of data where collection[i] == i % - * 256 + * @given very long collection of items of type uint8_t containing + * 2^30 == 1073741824 items this number takes ~ 1 Gb of data where + * collection[i] == i % 256 * @when encodeCollection is applied * @then obtain byte array of length 1073741824 + 5 bytes (header) bytes * where first bytes represent header, other are data itself @@ -434,22 +434,6 @@ struct ExplicitlyDefinedAsStatic : public std::vector { using Collection::Collection; }; -struct ExplicitlyDefinedAsDynamic : public std::vector { - static constexpr bool is_static_collection = false; - using Collection = std::vector; - using Collection::Collection; -}; - -struct ImplicitlyDefinedAsStatic : public std::array { - // using Collection = std::array; - // using Collection::Collection; -}; - -struct ImplicitlyDefinedAsDynamic : public std::vector { - using Collection = std::vector; - using Collection::Collection; -}; - TEST(Scale, encodeExplicitlyDefinedAsStatic) { using TestCollection = ExplicitlyDefinedAsStatic; @@ -466,6 +450,12 @@ TEST(Scale, encodeExplicitlyDefinedAsStatic) { decoded.begin(), decoded.end(), collection.begin(), collection.end())); } +struct ExplicitlyDefinedAsDynamic : public std::vector { + static constexpr bool is_static_collection = false; + using Collection = std::vector; + using Collection::Collection; +}; + TEST(Scale, encodeExplicitlyDefinedAsDynamic) { using TestCollection = ExplicitlyDefinedAsDynamic; @@ -481,6 +471,11 @@ TEST(Scale, encodeExplicitlyDefinedAsDynamic) { decoded.begin(), decoded.end(), collection.begin(), collection.end())); } +struct ImplicitlyDefinedAsStatic : public std::array { + // using Collection = std::array; + // using Collection::Collection; +}; + TEST(Scale, encodeImplicitlyDefinedAsStatic) { using TestCollection = ImplicitlyDefinedAsStatic; @@ -496,6 +491,11 @@ TEST(Scale, encodeImplicitlyDefinedAsStatic) { decoded.begin(), decoded.end(), collection.begin(), collection.end())); } +struct ImplicitlyDefinedAsDynamic : public std::vector { + using Collection = std::vector; + using Collection::Collection; +}; + TEST(Scale, encodeImplicitlyDefinedAsDynamic) { using TestCollection = ImplicitlyDefinedAsDynamic; @@ -510,3 +510,48 @@ TEST(Scale, encodeImplicitlyDefinedAsDynamic) { ASSERT_TRUE(std::equal( decoded.begin(), decoded.end(), collection.begin(), collection.end())); } + +struct StaticSpan : public std::span { + using Collection = std::span; + using Collection::Collection; +}; + +TEST(Scale, encodeStaticSpan) { + using TestCollection = StaticSpan; + + std::array original_data{1, 2, 3, 4, 5}; + const TestCollection collection(original_data); + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + std::array data{0xff, 0xff, 0xff, 0xff, 0xff}; + TestCollection decoded{data}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} + +struct DynamicSpan : public std::span { + using Collection = std::span; + using Collection::Collection; +}; + +TEST(Scale, encodeDynamicSpan) { + using TestCollection = DynamicSpan; + + std::vector original_data{1, 2, 3, 4, 5}; + const TestCollection collection(original_data); + ScaleEncoderStream s; + ASSERT_NO_THROW((s << collection)); + auto &&out = s.to_vector(); + + auto stream = ScaleDecoderStream(out); + + std::vector data{1, 2, 3, 4, 5}; + TestCollection decoded{data}; + stream >> decoded; + ASSERT_TRUE(std::equal( + decoded.begin(), decoded.end(), collection.begin(), collection.end())); +} From fc06c2f1c8f56ced279134703ced187da645f737 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 19 Oct 2023 18:46:53 +0300 Subject: [PATCH 08/19] update: bump version to 1.1.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c13edb..565d53d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ HunterGate( SHA1 72b446a4424ba28ea90f9a68a9134b0f8e44b5b2 ) -project(Scale LANGUAGES CXX VERSION 1.0.0) +project(Scale LANGUAGES CXX VERSION 1.1.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) From 10840d7efa33eedf8f95b710d59e99cb0d3d0a17 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Wed, 25 Oct 2023 16:01:50 +0300 Subject: [PATCH 09/19] fix: review issues Signed-off-by: Dmitriy Khaustov aka xDimon --- .../buffer/buffer_back_insert_iterator.hpp | 64 ------------------- include/scale/buffer/hexutil.hpp | 10 +-- src/buffer/hexutil.cpp | 10 ++- test/scale_collection_test.cpp | 3 +- 4 files changed, 12 insertions(+), 75 deletions(-) delete mode 100644 include/scale/buffer/buffer_back_insert_iterator.hpp diff --git a/include/scale/buffer/buffer_back_insert_iterator.hpp b/include/scale/buffer/buffer_back_insert_iterator.hpp deleted file mode 100644 index 7c72c5b..0000000 --- a/include/scale/buffer/buffer_back_insert_iterator.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "common/buffer.hpp" - -using scale::Buffer; - -namespace std { - - /* - * std::back_insert_iterator is an output iterator - * that appends to a container for which it was constructed. - */ - template <> - class back_insert_iterator { - public: - using value_type = Buffer::value_type; - using difference_type = typename std::vector::difference_type; - using pointer = Buffer::pointer; - using reference = typename std::vector::reference; - using iterator_category = std::random_access_iterator_tag; - - constexpr explicit back_insert_iterator(Buffer &c) : buf_{c} {} - - back_insert_iterator &operator=(uint8_t value) { - buf_.putUint8(value); - return *this; - } - - back_insert_iterator &operator=(uint32_t value) { - buf_.putUint32(value); - return *this; - } - - back_insert_iterator &operator=(uint64_t value) { - buf_.putUint64(value); - return *this; - } - - back_insert_iterator &operator=(const RangeOfBytes auto &range) { - buf_.put(range); - return *this; - } - - constexpr back_insert_iterator &operator*() { - return *this; - } - - constexpr back_insert_iterator &operator++() { - return *this; - } - - constexpr back_insert_iterator &operator++(int) { - return *this; - } - - private: - Buffer &buf_; - }; - -} // namespace std diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp index 3fbc7b6..663ed1c 100644 --- a/include/scale/buffer/hexutil.hpp +++ b/include/scale/buffer/hexutil.hpp @@ -38,7 +38,7 @@ namespace scale { * @param len length of bytes * @return hexstring */ - std::string hex_upper(const RangeOfBytes auto &bytes) noexcept; + std::string hex_upper(ConstSpanOfBytes bytes) noexcept; /** * @brief Converts bytes to hex representation @@ -46,18 +46,14 @@ namespace scale { * @param len length of bytes * @return hexstring */ - std::string hex_lower(const RangeOfBytes auto &bytes) noexcept { - std::string res(bytes.size() * 2, '\x00'); - boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); - return res; - } + std::string hex_lower(ConstSpanOfBytes bytes) noexcept; /** * @brief Converts bytes to hex representation with prefix 0x * @param array bytes * @return hexstring */ - std::string hex_lower_0x(RangeOfBytes auto bytes) noexcept; + std::string hex_lower_0x(ConstSpanOfBytes bytes) noexcept; /** * @brief Converts hex representation to bytes diff --git a/src/buffer/hexutil.cpp b/src/buffer/hexutil.cpp index c59aadb..67e390d 100644 --- a/src/buffer/hexutil.cpp +++ b/src/buffer/hexutil.cpp @@ -45,13 +45,19 @@ namespace scale { return str; } - std::string hex_upper(const RangeOfBytes auto &bytes) noexcept { + std::string hex_upper(ConstSpanOfBytes bytes) noexcept { std::string res(bytes.size() * 2, '\x00'); boost::algorithm::hex(bytes.begin(), bytes.end(), res.begin()); return res; } - std::string hex_lower_0x(const RangeOfBytes auto &bytes) noexcept { + std::string hex_lower(ConstSpanOfBytes bytes) noexcept { + std::string res(bytes.size() * 2, '\x00'); + boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); + return res; + } + + std::string hex_lower_0x(ConstSpanOfBytes bytes) noexcept { constexpr size_t prefix_len = sizeof("0x") - 1; std::string res(bytes.size() * 2 + prefix_len, '\x00'); diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index 0693fa7..ec3a331 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -472,8 +472,7 @@ TEST(Scale, encodeExplicitlyDefinedAsDynamic) { } struct ImplicitlyDefinedAsStatic : public std::array { - // using Collection = std::array; - // using Collection::Collection; + using Collection = std::array; }; TEST(Scale, encodeImplicitlyDefinedAsStatic) { From a3d9c0acf9fa5cfd6ecc1a8933af3598fc88b7cd Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Wed, 25 Oct 2023 16:18:14 +0300 Subject: [PATCH 10/19] fix: CI issues Signed-off-by: Dmitriy Khaustov aka xDimon --- include/scale/scale_decoder_stream.hpp | 12 ++++++------ include/scale/scale_encoder_stream.hpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index 27ed4e3..b968cd2 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -249,8 +249,8 @@ namespace scale { ScaleDecoderStream &operator>>(BitVec &v); ScaleDecoderStream &operator>>(DynamicSpan auto &collection) { - using size_type = std::decay_t::size_type; - using value_type = std::decay_t::value_type; + using size_type = typename std::decay_t::size_type; + using value_type = typename std::decay_t::value_type; CompactInteger size{0u}; *this >> size; @@ -272,8 +272,8 @@ namespace scale { * @return reference to stream */ ScaleDecoderStream &operator>>(ExtensibleBackCollection auto &collection) { - using size_type = std::decay_t::size_type; - using value_type = std::decay_t::value_type; + using size_type = typename std::decay_t::size_type; + using value_type = typename std::decay_t::value_type; CompactInteger size{0u}; *this >> size; @@ -305,8 +305,8 @@ namespace scale { */ ScaleDecoderStream &operator>>( RandomExtensibleCollection auto &collection) { - using size_type = std::decay_t::size_type; - using value_type = std::decay_t::value_type; + using size_type = typename std::decay_t::size_type; + using value_type = typename std::decay_t::value_type; CompactInteger size{0u}; *this >> size; diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index 6223f80..f1a28c6 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -176,7 +176,7 @@ namespace scale { * @return reference to stream */ ScaleEncoderStream &operator<<(std::string_view sv) { - return encodeDynamicCollection(ExplicitlyDynamic(sv)); + return encodeDynamicCollection(ExplicitlyDynamic{sv}); } /** From b29894855f59e5bfbe581abd4b38d563bb8eeaa7 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Wed, 25 Oct 2023 18:22:43 +0300 Subject: [PATCH 11/19] fix: remove remaining mentions of GSL Signed-off-by: Dmitriy Khaustov aka xDimon --- CMakeLists.txt | 3 --- include/scale/buffer/buffer.hpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 565d53d..5b9dac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,6 @@ option(BUILD_TESTS "Whether to include the test suite in build" OFF) hunter_add_package(Boost) find_package(Boost CONFIG REQUIRED) -hunter_add_package(Microsoft.GSL) -find_package(Microsoft.GSL CONFIG REQUIRED) - add_subdirectory(src) if (BUILD_TESTS) diff --git a/include/scale/buffer/buffer.hpp b/include/scale/buffer/buffer.hpp index 2e9df4d..aac93b8 100644 --- a/include/scale/buffer/buffer.hpp +++ b/include/scale/buffer/buffer.hpp @@ -165,7 +165,7 @@ namespace scale { /** * Returns a copy of a part of the buffer - * Works alike subspan() of gsl::span + * Works alike subspan() of std::span */ Buffer subbuffer(size_t offset = 0, size_t length = -1) const; From 65947936a4a22ed0a1ebacb5e7e5049572a52943 Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 25 Oct 2023 15:27:31 +0300 Subject: [PATCH 12/19] remove unused buffer --- include/scale/buffer/buffer.hpp | 258 -------------------------------- src/buffer/CMakeLists.txt | 1 - src/buffer/buffer.cpp | 177 ---------------------- test/scale_compact_test.cpp | 1 - test/util/literals.hpp | 12 -- 5 files changed, 449 deletions(-) delete mode 100644 include/scale/buffer/buffer.hpp delete mode 100644 src/buffer/buffer.cpp diff --git a/include/scale/buffer/buffer.hpp b/include/scale/buffer/buffer.hpp deleted file mode 100644 index aac93b8..0000000 --- a/include/scale/buffer/buffer.hpp +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include - -#include -#include - -#include -#include - -namespace scale { - - /** - * @brief Class represents arbitrary (including empty) byte buffer. - */ - class Buffer : public boost::equality_comparable, - public boost::equality_comparable, - public boost::equality_comparable>, - public boost::less_than_comparable { - public: - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; - using value_type = uint8_t; - // with this gsl::span can be built from Buffer - using pointer = typename std::vector::pointer; - using const_pointer = typename std::vector::const_pointer; - - /** - * @brief allocates buffer of size={@param size}, filled with {@param byte} - */ - Buffer(size_t size, uint8_t byte); - - ~Buffer() = default; - - /** - * @brief lvalue construct buffer from a byte vector - */ - explicit Buffer(std::vector vector); - explicit Buffer(const RangeOfBytes auto &range); - - Buffer(const uint8_t *begin, const uint8_t *end); - - Buffer() = default; - Buffer(const Buffer &b) = default; - Buffer(Buffer &&b) noexcept = default; - Buffer(std::initializer_list il); - - Buffer &reserve(size_t size); - Buffer &resize(size_t size); - - Buffer &operator=(const Buffer &other) = default; - Buffer &operator=(Buffer &&other) noexcept = default; - - Buffer &operator+=(const Buffer &other) noexcept; - - /** - * @brief Accessor of byte elements given {@param index} in bytearray - */ - uint8_t operator[](size_t index) const; - - /** - * @brief Accessor of byte elements given {@param index} in bytearray - */ - uint8_t &operator[](size_t index); - - /** - * @brief Lexicographical comparison of buffer content and range of bytes - */ - bool operator==(const RangeOfBytes auto &other) const noexcept; - - /** - * @brief Lexicographical comparison of buffer content and range of bytes - */ - bool operator<(const RangeOfBytes auto &other) const noexcept; - - /** - * @brief Iterator, which points to begin of this buffer. - */ - iterator begin(); - - /** - * @brief Iterator, which points to the element next to the last in this - * buffer. - */ - iterator end(); - - /** - * @brief Iterator, which points to begin of this buffer. - */ - const_iterator begin() const; - - /** - * @brief Iterator, which points to the element next to the last in this - * buffer. - */ - const_iterator end() const; - - /** - * @brief Getter for size of this buffer. - */ - size_t size() const; - - /** - * @brief Put a 8-bit {@param n} in this buffer. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint8(uint8_t n); - - /** - * @brief Put a 32-bit {@param n} number in this buffer. Will be serialized - * as big-endian number. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint32(uint32_t n); - - /** - * @brief Put a 64-bit {@param n} number in this buffer. Will be serialized - * as big-endian number. - * @return this buffer, suitable for chaining. - */ - Buffer &putUint64(uint64_t n); - - /** - * @brief Put a sequence of bytes into byte buffer - * @param s arbitrary span of bytes - * @return this buffer, suitable for chaining. - */ - Buffer &put(const RangeOfBytes auto &range); - - /** - * @brief Put a array of bytes bounded by pointers into byte buffer - * @param begin pointer to the array start - * end pointer to the address after the last element - * @return this buffer, suitable for chaining. - */ - Buffer &putBytes(const uint8_t *begin, const uint8_t *end); - - [[deprecated("Use Buffer::put() instead that")]] Buffer &putBuffer( - const Buffer &buf); - - /** - * Clear the contents of the Buffer - */ - void clear(); - - /** - * @brief getter for raw array of bytes - */ - const uint8_t *data() const; - uint8_t *data(); - - /** - * @brief getter for vector of bytes - */ - const std::vector &toVector() const; - - std::vector &toVector(); - - /** - * Returns a copy of a part of the buffer - * Works alike subspan() of std::span - */ - Buffer subbuffer(size_t offset = 0, size_t length = -1) const; - - /** - * @brief encode bytearray as hex - * @return hex-encoded string - */ - std::string toHex() const; - - /** - * Check if this buffer is empty - * @return true, if buffer is empty, false otherwise - */ - bool empty() const; - - /** - * @brief Construct Buffer from hex string - * @param hex hex-encoded string - * @return result containing constructed buffer if input string is - * hex-encoded string. - */ - static outcome::result fromHex(std::string_view hex); - - /** - * @brief return content of bytearray as string - * @note Does not ensure correct encoding - * @return string - */ - std::string_view toString() const; - - /** - * @brief return content of bytearray as a string copy data - * @note Does not ensure correct encoding - * @return string - */ - std::string asString() const; - - /** - * @brief stores content of a string to byte array - */ - static outcome::result fromString(const std::string &src); - - private: - std::vector data_; - - template - Buffer &putRange(const T &begin, const T &end); - }; - - /** - * @brief override operator<< for all streams except std::ostream - * @tparam Stream stream type - * @param s stream reference - * @param buffer value to encode - * @return reference to stream - */ - template > - Stream &operator<<(Stream &s, const Buffer &buffer) { - return s << buffer.toVector(); - } - - /** - * @brief decodes buffer object from stream - * @tparam Stream input stream type - * @param s stream reference - * @param buffer value to decode - * @return reference to stream - */ - template > - Stream &operator>>(Stream &s, Buffer &buffer) { - std::vector data; - s >> data; - buffer.put(data); - return s; - } - - std::ostream &operator<<(std::ostream &os, const Buffer &buffer); - -} // namespace scale - -namespace std { - template <> - struct hash { - size_t operator()(const scale::Buffer &x) const { - return boost::hash_range(x.begin(), x.end()); - } - }; -} // namespace std diff --git a/src/buffer/CMakeLists.txt b/src/buffer/CMakeLists.txt index d91d52b..d92084a 100644 --- a/src/buffer/CMakeLists.txt +++ b/src/buffer/CMakeLists.txt @@ -1,6 +1,5 @@ add_library(buffer - buffer.cpp hexutil.cpp ) target_include_directories(buffer PUBLIC diff --git a/src/buffer/buffer.cpp b/src/buffer/buffer.cpp deleted file mode 100644 index 6e92673..0000000 --- a/src/buffer/buffer.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include - -#include - -namespace scale { - - size_t Buffer::size() const { - return data_.size(); - } - - Buffer &Buffer::putUint32(uint32_t n) { - data_.push_back(static_cast((n >> 24) & 0xFF)); - data_.push_back(static_cast((n >> 16) & 0xFF)); - data_.push_back(static_cast((n >> 8) & 0xFF)); - data_.push_back(static_cast((n)&0xFF)); - - return *this; - } - - Buffer &Buffer::putUint64(uint64_t n) { - data_.push_back(static_cast((n >> 56u) & 0xFF)); - data_.push_back(static_cast((n >> 48u) & 0xFF)); - data_.push_back(static_cast((n >> 40u) & 0xFF)); - data_.push_back(static_cast((n >> 32u) & 0xFF)); - data_.push_back(static_cast((n >> 24u) & 0xFF)); - data_.push_back(static_cast((n >> 16u) & 0xFF)); - data_.push_back(static_cast((n >> 8u) & 0xFF)); - data_.push_back(static_cast((n)&0xFF)); - - return *this; - } - - std::string Buffer::toHex() const { - return hex_lower(data_); - } - - std::string_view Buffer::toString() const { - return {reinterpret_cast(data_.data()), // NOLINT - data_.size()}; - } - - bool Buffer::empty() const { - return data_.empty(); - } - - Buffer::Buffer(std::initializer_list il) : data_(il) {} - - Buffer::iterator Buffer::begin() { - return data_.begin(); - } - - Buffer::iterator Buffer::end() { - return data_.end(); - } - - Buffer &Buffer::putUint8(uint8_t n) { - data_.push_back(n); - return *this; - } - - uint8_t Buffer::operator[](size_t index) const { - return data_[index]; - } - - uint8_t &Buffer::operator[](size_t index) { - return data_[index]; - } - - outcome::result Buffer::fromHex(std::string_view hex) { - OUTCOME_TRY(bytes, unhex(hex)); - return Buffer{std::move(bytes)}; - } - - Buffer::Buffer(std::vector vector) : data_(std::move(vector)) {} - Buffer::Buffer(const RangeOfBytes auto &range) - : data_(range.begin(), range.end()) {} - - const std::vector &Buffer::toVector() const { - return data_; - } - - Buffer::const_iterator Buffer::begin() const { - return data_.begin(); - } - - Buffer::const_iterator Buffer::end() const { - return data_.end(); - } - - const uint8_t *Buffer::data() const { - return data_.data(); - } - - uint8_t *Buffer::data() { - return data_.data(); - } - - Buffer::Buffer(size_t size, uint8_t byte) : data_(size, byte) {} - - bool Buffer::operator==(const RangeOfBytes auto &other) const noexcept { - return std::equal(data_.begin(), data_.end(), other.begin(), other.end()); - } - - bool Buffer::operator<(const RangeOfBytes auto &other) const noexcept { - return std::lexicographical_compare( - begin(), end(), other.begin(), other.end()); - } - - template - Buffer &Buffer::putRange(const T &begin, const T &end) { - static_assert(sizeof(*begin) == 1); - data_.insert(std::end(data_), begin, end); - return *this; - } - - Buffer &Buffer::put(const RangeOfBytes auto &range) { - return putRange(range.begin(), range.end()); - } - - Buffer &Buffer::putBytes(const uint8_t *begin, const uint8_t *end) { - return putRange(begin, end); - } - - Buffer &Buffer::putBuffer(const Buffer &buf) { - return put(buf.toVector()); - } - - void Buffer::clear() { - data_.clear(); - } - - Buffer::Buffer(const uint8_t *begin, const uint8_t *end) - : data_{begin, end} {} - - std::vector &Buffer::toVector() { - return data_; - } - - Buffer &Buffer::reserve(size_t size) { - data_.reserve(size); - return *this; - } - - Buffer &Buffer::resize(size_t size) { - data_.resize(size); - return *this; - } - - std::string Buffer::asString() const { - return std::string{data_.begin(), data_.end()}; - } - - outcome::result Buffer::fromString(const std::string &src) { - return Buffer({src.begin(), src.end()}); - } - - Buffer Buffer::subbuffer(size_t offset, size_t length) const { - return Buffer(ConstSpanOfBytes(*this).subspan(offset, length)); - } - - Buffer &Buffer::operator+=(const Buffer &other) noexcept { - return this->put(other); - } - - std::ostream &operator<<(std::ostream &os, const Buffer &buffer) { - return os << buffer.toHex(); - } - -} // namespace scale diff --git a/test/scale_compact_test.cpp b/test/scale_compact_test.cpp index 43776d3..12d382a 100644 --- a/test/scale_compact_test.cpp +++ b/test/scale_compact_test.cpp @@ -14,7 +14,6 @@ #include "util/literals.hpp" #include "util/outcome.hpp" -using scale::Buffer; using scale::ByteArray; using scale::CompactInteger; using scale::decode; diff --git a/test/util/literals.hpp b/test/util/literals.hpp index 2d6847b..97bea3d 100644 --- a/test/util/literals.hpp +++ b/test/util/literals.hpp @@ -6,25 +6,13 @@ #pragma once -#include #include -/// creates a buffer filled with characters from the original string -/// mind that it does not perform unhexing, there is ""_unhex for it -inline scale::Buffer operator"" _buf(const char *c, size_t s) { - std::vector chars(c, c + s); - return scale::Buffer(std::move(chars)); -} - inline std::vector operator"" _v(const char *c, size_t s) { std::vector chars(c, c + s); return chars; } -inline scale::Buffer operator"" _hex2buf(const char *c, size_t s) { - return scale::Buffer::fromHex(std::string_view(c, s)).value(); -} - inline std::vector operator""_unhex(const char *c, size_t s) { if (s > 2 and c[0] == '0' and c[1] == 'x') return scale::unhexWith0x(std::string_view(c, s)).value(); From d0d1fe7e395e2740bfc35906b36968ffe5cbfe75 Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 25 Oct 2023 16:12:47 +0300 Subject: [PATCH 13/19] remove unused hex --- include/scale/buffer/hexutil.hpp | 51 -------------------------------- src/buffer/hexutil.cpp | 34 --------------------- test/util/literals.hpp | 5 ---- 3 files changed, 90 deletions(-) diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp index 663ed1c..8442e04 100644 --- a/include/scale/buffer/hexutil.hpp +++ b/include/scale/buffer/hexutil.hpp @@ -27,19 +27,6 @@ namespace scale { UNKNOWN }; - /** - * @brief Converts an integer to an uppercase hex representation - */ - std::string int_to_hex(uint64_t n, size_t fixed_width = 2) noexcept; - - /** - * @brief Converts bytes to uppercase hex representation - * @param array bytes - * @param len length of bytes - * @return hexstring - */ - std::string hex_upper(ConstSpanOfBytes bytes) noexcept; - /** * @brief Converts bytes to hex representation * @param array bytes @@ -48,13 +35,6 @@ namespace scale { */ std::string hex_lower(ConstSpanOfBytes bytes) noexcept; - /** - * @brief Converts bytes to hex representation with prefix 0x - * @param array bytes - * @return hexstring - */ - std::string hex_lower_0x(ConstSpanOfBytes bytes) noexcept; - /** * @brief Converts hex representation to bytes * @param array individual chars @@ -75,37 +55,6 @@ namespace scale { * @return unhexed buffer */ outcome::result> unhexWith0x(std::string_view hex); - - /** - * @brief unhex hex-string with 0x or without it in the beginning - * @tparam T unsigned integer value type to decode - * @param value source hex string - * @return unhexed value - */ - template >> - outcome::result unhexNumber(std::string_view value) { - std::vector bytes; - OUTCOME_TRY(bts, unhexWith0x(value)); - bytes = std::move(bts); - - if (bytes.size() > sizeof(T)) { - return UnhexError::VALUE_OUT_OF_RANGE; - } - - T result{0u}; - for (auto b : bytes) { - // check if `multiply by 10` will cause overflow - if constexpr (sizeof(T) > 1) { - result <<= 8u; - } else { - result = 0; - } - result += b; - } - - return result; - } - } // namespace scale OUTCOME_HPP_DECLARE_ERROR_2(scale, UnhexError) diff --git a/src/buffer/hexutil.cpp b/src/buffer/hexutil.cpp index 67e390d..d176eec 100644 --- a/src/buffer/hexutil.cpp +++ b/src/buffer/hexutil.cpp @@ -28,46 +28,12 @@ OUTCOME_CPP_DEFINE_CATEGORY_3(scale, UnhexError, e) { } namespace scale { - - std::string int_to_hex(uint64_t n, size_t fixed_width) noexcept { - std::stringstream result; - result.width(fixed_width); - result.fill('0'); - result << std::hex << std::uppercase << n; - auto str = result.str(); - if (str.length() % 2 != 0) { - str.push_back('\0'); - for (int64_t i = str.length() - 2; i >= 0; --i) { - str[i + 1] = str[i]; - } - str[0] = '0'; - } - return str; - } - - std::string hex_upper(ConstSpanOfBytes bytes) noexcept { - std::string res(bytes.size() * 2, '\x00'); - boost::algorithm::hex(bytes.begin(), bytes.end(), res.begin()); - return res; - } - std::string hex_lower(ConstSpanOfBytes bytes) noexcept { std::string res(bytes.size() * 2, '\x00'); boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); return res; } - std::string hex_lower_0x(ConstSpanOfBytes bytes) noexcept { - constexpr size_t prefix_len = sizeof("0x") - 1; - - std::string res(bytes.size() * 2 + prefix_len, '\x00'); - res.replace(0, prefix_len, "0x", prefix_len); - - boost::algorithm::hex_lower( - bytes.begin(), bytes.end(), res.begin() + prefix_len); - return res; - } - outcome::result> unhex(std::string_view hex) { std::vector blob; blob.reserve((hex.size() + 1) / 2); diff --git a/test/util/literals.hpp b/test/util/literals.hpp index 97bea3d..eed121a 100644 --- a/test/util/literals.hpp +++ b/test/util/literals.hpp @@ -8,11 +8,6 @@ #include -inline std::vector operator"" _v(const char *c, size_t s) { - std::vector chars(c, c + s); - return chars; -} - inline std::vector operator""_unhex(const char *c, size_t s) { if (s > 2 and c[0] == '0' and c[1] == 'x') return scale::unhexWith0x(std::string_view(c, s)).value(); From cda70c8379aba3d4a54174273ac54420993345ae Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 25 Oct 2023 16:13:43 +0300 Subject: [PATCH 14/19] remove concept --- include/scale/encode_append.hpp | 5 ----- include/scale/types.hpp | 5 ----- 2 files changed, 10 deletions(-) diff --git a/include/scale/encode_append.hpp b/include/scale/encode_append.hpp index e177b8a..3c7d842 100644 --- a/include/scale/encode_append.hpp +++ b/include/scale/encode_append.hpp @@ -44,9 +44,4 @@ namespace scale { */ outcome::result append_or_new_vec(std::vector &self_encoded, ConstSpanOfBytes input); - - inline outcome::result append_or_new_vec( - std::vector &self_encoded, const RangeOfBytes auto &input) { - return append_or_new_vec(self_encoded, ConstSpanOfBytes(input)); - } } // namespace scale diff --git a/include/scale/types.hpp b/include/scale/types.hpp index 127654a..a0e8cc4 100644 --- a/include/scale/types.hpp +++ b/include/scale/types.hpp @@ -35,11 +35,6 @@ namespace scale { OPT_FALSE = 2u, }; - template - concept RangeOfBytes = - std::ranges::sized_range and std::ranges::contiguous_range - and std::is_same_v>, uint8_t>; - template struct ExplicitlyStatic : public T { static constexpr bool is_static_collection = true; From 093dddf8bf6edcad87d975e741d4edce77af17f8 Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 25 Oct 2023 16:13:43 +0300 Subject: [PATCH 15/19] fix: remove redundant data structures Signed-off-by: Dmitriy Khaustov aka xDimon --- CMakeLists.txt | 2 +- include/scale/buffer/hexutil.hpp | 60 ---------- src/CMakeLists.txt | 4 - src/buffer/CMakeLists.txt | 11 -- src/buffer/hexutil.cpp | 68 ------------ test/CMakeLists.txt | 182 +++++++++++++++---------------- test/scale_boolean_test.cpp | 1 - test/scale_compact_test.cpp | 5 +- test/util/literals.hpp | 15 --- 9 files changed, 89 insertions(+), 259 deletions(-) delete mode 100644 include/scale/buffer/hexutil.hpp delete mode 100644 src/buffer/CMakeLists.txt delete mode 100644 src/buffer/hexutil.cpp delete mode 100644 test/util/literals.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b9dac9..6f28fd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ endif () include(GNUInstallDirs) -install(TARGETS scale buffer scale_encode_append EXPORT scaleConfig +install(TARGETS scale scale_encode_append EXPORT scaleConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/include/scale/buffer/hexutil.hpp b/include/scale/buffer/hexutil.hpp deleted file mode 100644 index 8442e04..0000000 --- a/include/scale/buffer/hexutil.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include - -#include - -#include -#include - -namespace scale { - - /** - * @brief error codes for exceptions that may occur during unhexing - */ - enum class UnhexError { - NOT_ENOUGH_INPUT = 1, - NON_HEX_INPUT, - VALUE_OUT_OF_RANGE, - MISSING_0X_PREFIX, - UNKNOWN - }; - - /** - * @brief Converts bytes to hex representation - * @param array bytes - * @param len length of bytes - * @return hexstring - */ - std::string hex_lower(ConstSpanOfBytes bytes) noexcept; - - /** - * @brief Converts hex representation to bytes - * @param array individual chars - * @param len length of chars - * @return result containing array of bytes if input string is hex encoded and - * has even length - * - * @note reads both uppercase and lowercase hexstrings - * - * @see - * https://www.boost.org/doc/libs/1_51_0/libs/algorithm/doc/html/the_boost_algorithm_library/Misc/hex.html - */ - outcome::result> unhex(std::string_view hex); - - /** - * @brief Unhex hex-string with 0x in the begining - * @param hex hex string with 0x in the beginning - * @return unhexed buffer - */ - outcome::result> unhexWith0x(std::string_view hex); -} // namespace scale - -OUTCOME_HPP_DECLARE_ERROR_2(scale, UnhexError) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cadfcb4..e4aa95c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,3 @@ - -add_subdirectory(buffer) - add_library(scale scale_decoder_stream.cpp scale_encoder_stream.cpp @@ -13,7 +10,6 @@ target_include_directories(scale PUBLIC ) target_link_libraries(scale Boost::boost - buffer ) add_library(scale_encode_append diff --git a/src/buffer/CMakeLists.txt b/src/buffer/CMakeLists.txt deleted file mode 100644 index d92084a..0000000 --- a/src/buffer/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ - -add_library(buffer - hexutil.cpp - ) -target_include_directories(buffer PUBLIC - $ - $ - ) -target_link_libraries(buffer - Boost::boost - ) diff --git a/src/buffer/hexutil.cpp b/src/buffer/hexutil.cpp deleted file mode 100644 index d176eec..0000000 --- a/src/buffer/hexutil.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "scale/buffer/hexutil.hpp" - -#include - -#include - -OUTCOME_CPP_DEFINE_CATEGORY_3(scale, UnhexError, e) { - using scale::UnhexError; - switch (e) { - case UnhexError::NON_HEX_INPUT: - return "Input contains non-hex characters"; - case UnhexError::NOT_ENOUGH_INPUT: - return "Input contains odd number of characters"; - case UnhexError::VALUE_OUT_OF_RANGE: - return "Decoded value is out of range of requested type"; - case UnhexError::MISSING_0X_PREFIX: - return "Missing expected 0x prefix"; - case UnhexError::UNKNOWN: - return "Unknown error"; - } - return "Unknown error (error id not listed)"; -} - -namespace scale { - std::string hex_lower(ConstSpanOfBytes bytes) noexcept { - std::string res(bytes.size() * 2, '\x00'); - boost::algorithm::hex_lower(bytes.begin(), bytes.end(), res.begin()); - return res; - } - - outcome::result> unhex(std::string_view hex) { - std::vector blob; - blob.reserve((hex.size() + 1) / 2); - - try { - boost::algorithm::unhex(hex.begin(), hex.end(), std::back_inserter(blob)); - return blob; - - } catch (const boost::algorithm::not_enough_input &) { - return UnhexError::NOT_ENOUGH_INPUT; - - } catch (const boost::algorithm::non_hex_input &) { - return UnhexError::NON_HEX_INPUT; - - } catch (const std::exception &) { - return UnhexError::UNKNOWN; - } - } - - outcome::result> unhexWith0x( - std::string_view hex_with_prefix) { - const static std::string leading_chrs = "0x"; - - if (hex_with_prefix.substr(0, leading_chrs.size()) != leading_chrs) { - return UnhexError::MISSING_0X_PREFIX; - } - - auto without_prefix = hex_with_prefix.substr(leading_chrs.size()); - - return unhex(without_prefix); - } -} // namespace scale diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 49a90ab..e711fed 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,156 +6,148 @@ # The target_sources() command converts relative paths to absolute. if (POLICY CMP0076) - cmake_policy(SET CMP0076 NEW) + cmake_policy(SET CMP0076 NEW) endif () hunter_add_package(GTest) find_package(GTest CONFIG REQUIRED) function(disable_clang_tidy target) - set_target_properties(${target} PROPERTIES - C_CLANG_TIDY "" - CXX_CLANG_TIDY "" - ) + set_target_properties(${target} PROPERTIES + C_CLANG_TIDY "" + CXX_CLANG_TIDY "" + ) endfunction() function(addtest test_name) - add_executable(${test_name} ${ARGN}) - target_sources(${test_name} PUBLIC - ${ARGN} - ) - target_link_libraries(${test_name} - GTest::gtest - GTest::gmock_main - ) - target_include_directories(${test_name} PRIVATE - ${PROJECT_SOURCE_DIR}/include - ) - set(xml_output "--gtest_output=xml:${CMAKE_BINARY_DIR}/xunit/xunit-${test_name}.xml") - add_test( - NAME ${test_name} - COMMAND $ ${xml_output} - ) - set_target_properties(${test_name} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests_bin - ARCHIVE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests_lib - LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests_lib - ) - disable_clang_tidy(${test_name}) + add_executable(${test_name} ${ARGN}) + target_sources(${test_name} PUBLIC + ${ARGN} + ) + target_link_libraries(${test_name} + GTest::gtest + GTest::gmock_main + ) + target_include_directories(${test_name} PRIVATE + ${PROJECT_SOURCE_DIR}/include + ) + set(xml_output "--gtest_output=xml:${CMAKE_BINARY_DIR}/xunit/xunit-${test_name}.xml") + add_test( + NAME ${test_name} + COMMAND $ ${xml_output} + ) + set_target_properties(${test_name} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests_bin + ARCHIVE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests_lib + LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests_lib + ) + disable_clang_tidy(${test_name}) endfunction() # for tests' XML reports file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/xunit) addtest(scale_decoder_stream_test - scale_decoder_stream_test.cpp - ) + scale_decoder_stream_test.cpp +) target_link_libraries(scale_decoder_stream_test - scale - ) + scale +) addtest(scale_encode_append_test - scale_encode_append_test.cpp - ) + scale_encode_append_test.cpp +) target_link_libraries(scale_encode_append_test - scale_encode_append - ) + scale_encode_append +) addtest(scale_compact_test - scale_compact_test.cpp - ) + scale_compact_test.cpp +) target_link_libraries(scale_compact_test - scale - buffer - ) + scale +) addtest(scale_enum_test - scale_enum_test.cpp - ) + scale_enum_test.cpp +) target_link_libraries(scale_enum_test - scale - buffer - ) + scale +) addtest(scale_fixed_test - scale_fixed_test.cpp - ) + scale_fixed_test.cpp +) target_link_libraries(scale_fixed_test - scale - buffer - ) + scale +) addtest(scale_boolean_test - scale_boolean_test.cpp - ) + scale_boolean_test.cpp +) target_link_libraries(scale_boolean_test - scale - buffer - ) + scale +) addtest(scale_optional_test - scale_optional_test.cpp - ) + scale_optional_test.cpp +) target_link_libraries(scale_optional_test - scale - buffer - ) + scale +) addtest(scale_collection_test - scale_collection_test.cpp - ) + scale_collection_test.cpp +) target_link_libraries(scale_collection_test - scale - buffer - ) + scale +) addtest(scale_variant_test - scale_variant_test.cpp - ) + scale_variant_test.cpp +) target_link_libraries(scale_variant_test - scale - buffer - ) + scale +) addtest(scale_pair_test - scale_pair_test.cpp - ) + scale_pair_test.cpp +) target_link_libraries(scale_pair_test - scale - buffer - ) + scale +) addtest(scale_strings_test - scale_strings_test.cpp - ) + scale_strings_test.cpp +) target_link_libraries(scale_strings_test - scale - ) + scale +) addtest(scale_convenience_functions_test - scale_convenience_functions_test.cpp - ) + scale_convenience_functions_test.cpp +) target_link_libraries(scale_convenience_functions_test - scale - ) + scale +) addtest(scale_tuple_test - scale_tuple_test.cpp - ) + scale_tuple_test.cpp +) target_link_libraries(scale_tuple_test - scale - ) + scale +) addtest(scale_array_test - scale_array_test.cpp - ) + scale_array_test.cpp +) target_link_libraries(scale_array_test - scale - ) + scale +) addtest(scale_encode_counter_test - scale_encode_counter_test.cpp - ) + scale_encode_counter_test.cpp +) target_link_libraries(scale_encode_counter_test - scale - ) + scale +) diff --git a/test/scale_boolean_test.cpp b/test/scale_boolean_test.cpp index c911caa..ad08ba5 100644 --- a/test/scale_boolean_test.cpp +++ b/test/scale_boolean_test.cpp @@ -11,7 +11,6 @@ #include "scale/scale_encoder_stream.hpp" #include "scale/scale_error.hpp" -#include "util/literals.hpp" #include "util/outcome.hpp" using scale::ByteArray; diff --git a/test/scale_compact_test.cpp b/test/scale_compact_test.cpp index 12d382a..8a1caac 100644 --- a/test/scale_compact_test.cpp +++ b/test/scale_compact_test.cpp @@ -11,7 +11,6 @@ #include #include -#include "util/literals.hpp" #include "util/outcome.hpp" using scale::ByteArray; @@ -112,9 +111,7 @@ INSTANTIATE_TEST_SUITE_P( "224945689727159819140526925384299092943484855915095831" "655037778630591879033574393515952034305194542857496045" "531676044756160413302774714984450425759043258192756735"), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFF"_unhex))); + std::vector(68, 0xFF)))); /** * Negative tests diff --git a/test/util/literals.hpp b/test/util/literals.hpp deleted file mode 100644 index eed121a..0000000 --- a/test/util/literals.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright Quadrivium LLC - * All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include - -inline std::vector operator""_unhex(const char *c, size_t s) { - if (s > 2 and c[0] == '0' and c[1] == 'x') - return scale::unhexWith0x(std::string_view(c, s)).value(); - return scale::unhex(std::string_view(c, s)).value(); -} From 8cd50c2de62ea5456a34da311c1b99749507f7ab Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Wed, 25 Oct 2023 19:00:45 +0300 Subject: [PATCH 16/19] update: .gitignore Signed-off-by: Dmitriy Khaustov aka xDimon --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ce212f2..a40c0ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -build .vscode .idea -cmake-build-*/ \ No newline at end of file +**/build/ +**/build-*/ +**/cmake-build-*/ From 2a223956d9cc0c78a95848da2fd1be35b2a4bd2d Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Wed, 25 Oct 2023 19:22:36 +0300 Subject: [PATCH 17/19] update: .gitignore Signed-off-by: Dmitriy Khaustov aka xDimon --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a40c0ea..241838c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ **/build/ **/build-*/ **/cmake-build-*/ +Testing From 1e7a54a0090e8378c6ca4ca07fb661cba621b6df Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 26 Oct 2023 15:11:09 +0300 Subject: [PATCH 18/19] refactor: prohibit potentially dangerous implementation Signed-off-by: Dmitriy Khaustov aka xDimon --- include/scale/scale_decoder_stream.hpp | 24 +++++------------------- test/scale_collection_test.cpp | 23 ----------------------- 2 files changed, 5 insertions(+), 42 deletions(-) diff --git a/include/scale/scale_decoder_stream.hpp b/include/scale/scale_decoder_stream.hpp index b968cd2..9314c81 100644 --- a/include/scale/scale_decoder_stream.hpp +++ b/include/scale/scale_decoder_stream.hpp @@ -248,23 +248,9 @@ namespace scale { */ ScaleDecoderStream &operator>>(BitVec &v); - ScaleDecoderStream &operator>>(DynamicSpan auto &collection) { - using size_type = typename std::decay_t::size_type; - using value_type = typename std::decay_t::value_type; - - CompactInteger size{0u}; - *this >> size; - - auto item_count = size.convert_to(); - if (item_count > collection.size()) { - raise(DecodeError::TOO_MANY_ITEMS); - } - - for (auto &item : collection) { - *this >> item; - } - return *this; - } + /// @note Implementation prohibited as potentially dangerous. + /// Use manual decoding instead + ScaleDecoderStream &operator>>(DynamicSpan auto &collection) = delete; /** * @brief scale-decodes to sequential collection (which can be reserved @@ -273,7 +259,6 @@ namespace scale { */ ScaleDecoderStream &operator>>(ExtensibleBackCollection auto &collection) { using size_type = typename std::decay_t::size_type; - using value_type = typename std::decay_t::value_type; CompactInteger size{0u}; *this >> size; @@ -306,7 +291,8 @@ namespace scale { ScaleDecoderStream &operator>>( RandomExtensibleCollection auto &collection) { using size_type = typename std::decay_t::size_type; - using value_type = typename std::decay_t::value_type; + using value_type = + typename std::decay_t::value_type; CompactInteger size{0u}; *this >> size; diff --git a/test/scale_collection_test.cpp b/test/scale_collection_test.cpp index ec3a331..731fd23 100644 --- a/test/scale_collection_test.cpp +++ b/test/scale_collection_test.cpp @@ -531,26 +531,3 @@ TEST(Scale, encodeStaticSpan) { ASSERT_TRUE(std::equal( decoded.begin(), decoded.end(), collection.begin(), collection.end())); } - -struct DynamicSpan : public std::span { - using Collection = std::span; - using Collection::Collection; -}; - -TEST(Scale, encodeDynamicSpan) { - using TestCollection = DynamicSpan; - - std::vector original_data{1, 2, 3, 4, 5}; - const TestCollection collection(original_data); - ScaleEncoderStream s; - ASSERT_NO_THROW((s << collection)); - auto &&out = s.to_vector(); - - auto stream = ScaleDecoderStream(out); - - std::vector data{1, 2, 3, 4, 5}; - TestCollection decoded{data}; - stream >> decoded; - ASSERT_TRUE(std::equal( - decoded.begin(), decoded.end(), collection.begin(), collection.end())); -} From 88d5b79d0759676af8a2f86e64f742627eba293e Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon Date: Thu, 26 Oct 2023 16:01:34 +0300 Subject: [PATCH 19/19] refactor: return implementation for vector Signed-off-by: Dmitriy Khaustov aka xDimon --- include/scale/scale_encoder_stream.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/scale/scale_encoder_stream.hpp b/include/scale/scale_encoder_stream.hpp index f1a28c6..78fd7bd 100644 --- a/include/scale/scale_encoder_stream.hpp +++ b/include/scale/scale_encoder_stream.hpp @@ -179,6 +179,19 @@ namespace scale { return encodeDynamicCollection(ExplicitlyDynamic{sv}); } + /** + * @brief scale-encodes a vector of bool + * @param v vector of bool + * @return reference to stream + */ + ScaleEncoderStream &operator<<(const std::vector &v) { + *this << CompactInteger{v.size()}; + for (bool el : v) { + *this << el; + } + return *this; + } + /** * @brief scale-encodes any integral type including bool * @tparam T integral type