aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/utility/TslHelper.hpp
blob: a8bd0bdc129ab650eaf32bf0631f4915929473dd (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once

#include <type_traits>

#include <tsl/ordered_map.h>
#include <tsl/ordered_set.h>

#include "openvic-simulation/types/OrderedContainers.hpp"
#include "openvic-simulation/utility/Utility.hpp"

namespace OpenVic {
   template<IsOrderedMap Map, typename Key = typename Map::key_type, typename Mapped = typename Map::mapped_type>
   struct _OrderedMapMutable {
      using map_type = Map;
      struct ordered_iterator {
         using key_type = Key;
         using mapped_type = Mapped;
         using pair_type = std::pair<key_type const&, mapped_type&>;
         using value_type = pair_type;
         using iterator = typename map_type::iterator;

         using iterator_category = std::random_access_iterator_tag;
         using difference_type = typename map_type::values_container_type::iterator::difference_type;

         pair_type operator*() {
            return { m_iterator.key(), m_iterator.value() };
         }

         ordered_iterator& operator++() {
            ++m_iterator;
            return *this;
         }
         ordered_iterator& operator--() {
            --m_iterator;
            return *this;
         }

         ordered_iterator operator++(int) {
            ordered_iterator tmp(*this);
            ++(*this);
            return tmp;
         }
         ordered_iterator operator--(int) {
            ordered_iterator tmp(*this);
            --(*this);
            return tmp;
         }

         pair_type operator[](difference_type n) {
            return *(*this + n);
         }

         ordered_iterator& operator+=(difference_type n) {
            m_iterator += n;
            return *this;
         }
         ordered_iterator& operator-=(difference_type n) {
            m_iterator -= n;
            return *this;
         }

         ordered_iterator operator+(difference_type n) {
            ordered_iterator tmp(*this);
            tmp += n;
            return tmp;
         }
         ordered_iterator operator-(difference_type n) {
            ordered_iterator tmp(*this);
            tmp -= n;
            return tmp;
         }

         bool operator==(ordered_iterator const& rhs) const {
            return m_iterator == rhs.m_iterator;
         }

         bool operator!=(ordered_iterator const& rhs) const {
            return m_iterator != rhs.m_iterator;
         }

         bool operator<(ordered_iterator const& rhs) const {
            return m_iterator < rhs.m_iterator;
         }

         bool operator>(ordered_iterator const& rhs) const {
            return m_iterator > rhs.m_iterator;
         }

         bool operator<=(ordered_iterator const& rhs) const {
            return m_iterator <= rhs.m_iterator;
         }

         bool operator>=(ordered_iterator const& rhs) const {
            return m_iterator >= rhs.m_iterator;
         }

         friend ordered_iterator operator+(difference_type n, ordered_iterator const& it) {
            return n + it.m_iterator;
         }

         ordered_iterator operator+(ordered_iterator const& rhs) const {
            return m_iterator + rhs.m_iterator;
         }

         difference_type operator-(ordered_iterator const& rhs) const {
            return m_iterator - rhs.m_iterator;
         }

         iterator m_iterator;
      };

      _OrderedMapMutable(map_type& map) : _map(map) {}

      ordered_iterator begin() {
         return ordered_iterator { _map.begin() };
      }
      ordered_iterator end() {
         return ordered_iterator { _map.end() };
      }

   private:
      map_type& _map;
   };

   template<IsOrderedMap Map, typename Key = typename Map::key_type, typename Mapped = typename Map::mapped_type>
   _OrderedMapMutable<Map, Key, Mapped> mutable_iterator(Map& map) {
      return _OrderedMapMutable<Map, Key, Mapped> { map };
   }
}