aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/enum_serialization_runtime/dispatch_methods.h
blob: db752ae7108878308df6554eee47e23f119991fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#pragma once

#include "ordered_pairs.h"

#include <util/generic/strbuf.h>
#include <util/stream/fwd.h>

namespace NEnumSerializationRuntime {
    // compile-time conversion method selection

    constexpr size_t LINEAR_SEARCH_KEYS_SIZE_THRESHOLD = 6;
    constexpr size_t LINEAR_SEARCH_VALUES_SIZE_THRESHOLD = 2;

    template <class TNameBufs, typename EEnum>
    inline void DispatchOutFn(IOutputStream& os, EEnum n) {
        constexpr auto order = TNameBufs::NamesOrder;
        if constexpr (order >= ::NEnumSerializationRuntime::ESortOrder::DirectMapping) {
            return TNameBufs::OutDirect(&os, n, TNameBufs::EnumInitializationData);
        } else if constexpr (std::size(TNameBufs::EnumInitializationData.NamesInitializer) <= LINEAR_SEARCH_KEYS_SIZE_THRESHOLD) {
            return TNameBufs::OutFullScan(&os, n, TNameBufs::EnumInitializationData);
        } else if constexpr (order >= ::NEnumSerializationRuntime::ESortOrder::Ascending) {
            return TNameBufs::OutSorted(&os, n, TNameBufs::EnumInitializationData);
        } else {
            const TNameBufs& names = TNameBufs::Instance();
            return names.Out(&os, n);
        }
    }

    template <class TNameBufs, typename EEnum>
    inline EEnum DispatchFromStringImplFn(const char* data, size_t len) {
        const TStringBuf name{data, len};
        constexpr auto order = TNameBufs::ValuesOrder;
        static_assert(order >= ::NEnumSerializationRuntime::ESortOrder::Ascending, "enum_parser produced unsorted output"); // comment this line to use run-time sort for temporary workaround
        if constexpr (std::size(TNameBufs::EnumInitializationData.ValuesInitializer) <= LINEAR_SEARCH_VALUES_SIZE_THRESHOLD) {
            return TNameBufs::FromStringFullScan(name, TNameBufs::EnumInitializationData);
        } else if constexpr (order >= ::NEnumSerializationRuntime::ESortOrder::Ascending) {
            return TNameBufs::FromStringSorted(name, TNameBufs::EnumInitializationData);
        } else {
            const TNameBufs& names = TNameBufs::Instance();
            return names.FromString(name);
        }
    }

    template <class TNameBufs, typename EEnum>
    inline bool DispatchTryFromStringImplFn(const char* data, size_t len, EEnum& result) {
        const TStringBuf name{data, len};
        constexpr auto order = TNameBufs::ValuesOrder;
        if constexpr (std::size(TNameBufs::EnumInitializationData.ValuesInitializer) <= LINEAR_SEARCH_VALUES_SIZE_THRESHOLD) {
            return TNameBufs::TryFromStringFullScan(name, result, TNameBufs::EnumInitializationData);
        } else if constexpr (order >= ::NEnumSerializationRuntime::ESortOrder::Ascending) {
            return TNameBufs::TryFromStringSorted(name, result, TNameBufs::EnumInitializationData);
        } else {
            const TNameBufs& names = TNameBufs::Instance();
            return names.FromString(name, result);
        }
    }
}