• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

afxres / binary-cxx / 14380371690

10 Apr 2025 12:25PM UTC coverage: 99.352% (-0.3%) from 99.673%
14380371690

push

github

afxres
Use functions for variant converter

32 of 33 new or added lines in 1 file covered. (96.97%)

1 existing line in 1 file now uncovered.

613 of 617 relevant lines covered (99.35%)

95.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/code/binary/include/binary/converters/VariantConverter.hpp
1
#ifndef BINARY_CONVERTERS_VARIANTCONVERTER_HPP
2
#define BINARY_CONVERTERS_VARIANTCONVERTER_HPP
3

4
#include <memory>
5
#include <variant>
6

7
#include "binary/Converter.hpp"
8
#include "binary/ConverterExtensions.hpp"
9

10
namespace binary::converters {
11
template <typename T>
12
class VariantConverter;
13

14
template <template <typename...> typename T, typename... E>
15
    requires requires { std::variant_size<T<E...>>::value; }
16
class VariantConverter<T<E...>> : public Converter<T<E...>> {
17
private:
18
    using ConverterTargetType = T<E...>;
19
    using EncodeFunction = std::function<void(Allocator&, const ConverterTargetType&)>;
20
    using DecodeFunction = std::function<ConverterTargetType(std::span<const std::byte>&)>;
21

22
    struct MethodInfo {
23
        EncodeFunction Encode;
24
        EncodeFunction EncodeAuto;
25
        DecodeFunction Decode;
26
        DecodeFunction DecodeAuto;
27
    };
28

29
    template <size_t Index>
30
    static MethodInfo GetMethodInfo(const auto& converter) {
49✔
31
        MethodInfo result;
49✔
32
        result.Encode = [converter](auto& allocator, const auto& item) { converter->Encode(allocator, std::get<Index>(item)); };
57✔
33
        result.EncodeAuto = [converter](auto& allocator, const auto& item) { converter->EncodeAuto(allocator, std::get<Index>(item)); };
57✔
34
        result.Decode = [converter](auto& span) { return ConverterTargetType(std::in_place_index<Index>, converter->Decode(span)); };
57✔
35
        result.DecodeAuto = [converter](auto& span) { return ConverterTargetType(std::in_place_index<Index>, converter->DecodeAuto(span)); };
57✔
36
        return result;
49✔
UNCOV
37
    }
×
38

39
    template <size_t... Index>
40
    static std::vector<MethodInfo> GetMethodInfoList(const std::shared_ptr<Converter<std::remove_cv_t<E>>>&... converter, std::index_sequence<Index...>) {
21✔
41
        std::vector<MethodInfo> result;
21✔
42
        (result.emplace_back(GetMethodInfo<Index>(converter)), ...);
21✔
43
        return result;
21✔
NEW
44
    }
×
45

46
    template <size_t IsAuto>
47
    void EncodeInternal(Allocator& allocator, const ConverterTargetType& item) {
17✔
48
        auto header = item.index();
17✔
49
        const auto& record = this->record;
17✔
50
        if (header >= record.size()) {
17✔
51
            throw std::invalid_argument("invalid variant value");
1✔
52
        }
53

54
        ::binary::Encode(allocator, header);
16✔
55
        if constexpr (IsAuto == 0) {
56
            record.at(header).Encode(allocator, item);
8✔
57
        } else {
58
            record.at(header).EncodeAuto(allocator, item);
8✔
59
        }
60
    }
16✔
61

62
    template <size_t IsAuto>
63
    ConverterTargetType DecodeInternal(std::span<const std::byte>& span) {
28✔
64
        auto header = ::binary::Decode(span);
28✔
65
        const auto& record = this->record;
28✔
66
        if (header >= record.size()) {
28✔
67
            throw std::invalid_argument("invalid variant index");
12✔
68
        }
69

70
        if constexpr (IsAuto == 0) {
71
            return record.at(header).Decode(span);
8✔
72
        } else {
73
            return record.at(header).DecodeAuto(span);
8✔
74
        }
75
    }
76

77
    const std::vector<MethodInfo> record;
78

79
public:
80
    VariantConverter(const std::shared_ptr<Converter<std::remove_cv_t<E>>>&... converter)
21✔
81
        : record(GetMethodInfoList(converter..., std::make_index_sequence<sizeof...(E)>())) {}
21✔
82

83
    virtual void Encode(Allocator& allocator, const ConverterTargetType& item) override {
9✔
84
        EncodeInternal<0>(allocator, item);
9✔
85
    }
8✔
86

87
    virtual void EncodeAuto(Allocator& allocator, const ConverterTargetType& item) override {
8✔
88
        EncodeInternal<1>(allocator, item);
8✔
89
    }
8✔
90

91
    virtual ConverterTargetType Decode(const std::span<const std::byte>& span) override {
14✔
92
        std::span<const std::byte> copy = span;
14✔
93
        return DecodeInternal<0>(copy);
22✔
94
    }
95

96
    virtual ConverterTargetType DecodeAuto(std::span<const std::byte>& span) override {
14✔
97
        return DecodeInternal<1>(span);
14✔
98
    }
99
};
100
}
101

102
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc