aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/utility/StringLiteral.hpp
blob: 1298254a992ff5a1290af742d7bdb69f7174029e (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <string_view>
#include <type_traits>

namespace OpenVic {
   template<std::size_t N>
   struct StringLiteral {
      constexpr StringLiteral(const char (&str)[N]) {
         std::copy_n(str, N, value);
      }

      consteval StringLiteral(std::string_view string) {
         assert(string.size() == N);
         std::copy_n(string.begin(), N, value);
      }

      char value[N];
      static const constexpr std::integral_constant<std::size_t, N - 1> size {};

      struct iterator {
         using iterator_concept [[maybe_unused]] = std::contiguous_iterator_tag;
         using difference_type = std::ptrdiff_t;
         using element_type = const char; // element_type is a reserved name that must be used in the definition
         using pointer = element_type*;
         using reference = element_type&;

         constexpr iterator() = default;
         constexpr iterator(pointer p) : _ptr(p) {}
         constexpr reference operator*() const {
            return *_ptr;
         }
         constexpr pointer operator->() const {
            return _ptr;
         }
         constexpr auto& operator++() {
            _ptr++;
            return *this;
         }
         constexpr auto operator++(int) {
            auto tmp = *this;
            ++(*this);
            return tmp;
         }
         constexpr iterator& operator+=(int i) {
            _ptr += i;
            return *this;
         }
         constexpr iterator operator+(const difference_type other) const {
            return _ptr + other;
         }
         constexpr friend iterator operator+(const difference_type value, iterator const& other) {
            return other + value;
         }
         constexpr iterator& operator--() {
            _ptr--;
            return *this;
         }
         constexpr iterator operator--(int) {
            iterator tmp = *this;
            --(*this);
            return tmp;
         }
         constexpr iterator& operator-=(int i) {
            _ptr -= i;
            return *this;
         }
         constexpr difference_type operator-(iterator const& other) const {
            return _ptr - other._ptr;
         }
         constexpr iterator operator-(const difference_type other) const {
            return _ptr - other;
         }
         friend iterator operator-(const difference_type value, iterator const& other) {
            return other - value;
         }
         constexpr reference operator[](difference_type idx) const {
            return _ptr[idx];
         }
         constexpr auto operator<=>(iterator const&) const = default; // three-way comparison C++20

      private:
         pointer _ptr;
      };

      constexpr iterator begin() const {
         return iterator { &value };
      }

      constexpr iterator end() const {
         return iterator { &value + N };
      }

      constexpr operator std::string_view() const {
         return std::string_view { value, N };
      }

      constexpr decltype(auto) data() const {
         return static_cast<std::string_view>(*this).data();
      }
   };
}