aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/enum_serialization_runtime/ordered_pairs.h
blob: 874c70941838d24e78646f93cbb1f50eb521f2f1 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#pragma once

#include <util/generic/array_ref.h>
#include <util/generic/strbuf.h>

namespace NEnumSerializationRuntime {
    enum class ESortOrder: int {
        Unordered = 0,
        Ascending = 1,
        StrictlyAscending = 2,
        DirectMapping = 3,
    };

    template <typename TEnumRepresentationType>
    struct TEnumStringPair {
        const TEnumRepresentationType Key;
        const TStringBuf Name;
    };

    template <typename TEnumRepresentationType>
    constexpr ESortOrder GetKeyFieldSortOrder(const TArrayRef<const TEnumStringPair<TEnumRepresentationType>> initializer) {
        if (initializer.empty()) {
            return ESortOrder::DirectMapping;
        }
        bool direct = true;
        bool strict = true;
        bool sorted = true;
        TEnumRepresentationType expected = initializer.data()[0].Key;
        for (size_t i = 1; i < initializer.size(); ++i) {
            const auto& prev = initializer.data()[i - 1].Key;
            const auto& next = initializer.data()[i - 0].Key;
            if (++expected != next) {
                direct = false;
            }
            if (prev >= next) {
                strict = false;
            }
            if (prev > next) {
                sorted = false;
                break;
            }
        }
        return direct   ? ESortOrder::DirectMapping
               : strict ? ESortOrder::StrictlyAscending
               : sorted ? ESortOrder::Ascending
                        : ESortOrder::Unordered;
    }

    template <typename TEnumRepresentationType>
    constexpr ESortOrder GetNameFieldSortOrder(const TArrayRef<const TEnumStringPair<TEnumRepresentationType>> initializer) {
        if (initializer.empty()) {
            return ESortOrder::DirectMapping;
        }
        bool strict = true;
        bool sorted = true;
        for (size_t i = 1; i < initializer.size(); ++i) {
            const std::string_view prev = initializer.data()[i - 1].Name;
            const std::string_view next = initializer.data()[i - 0].Name;
            if (prev >= next) {
                strict = false;
            }
            if (prev > next) {
                sorted = false;
                break;
            }
        }
        return strict   ? ESortOrder::StrictlyAscending
               : sorted ? ESortOrder::Ascending
                        : ESortOrder::Unordered;
    }
}