Loading...
Searching...
No Matches
IdentifierGeneration.hpp
1#pragma once
2#include <score/model/Identifier.hpp>
3#include <score/tools/std/ArrayView.hpp>
4#include <score/tools/std/Optional.hpp>
5
6#include <sys/types.h>
7
8#include <score_lib_base_export.h>
9
10#include <cstddef>
11#include <type_traits>
12#include <vector>
13
14namespace score
15{
19struct SCORE_LIB_BASE_EXPORT random_id_generator
20{
25 static int32_t getRandomId();
26 static int32_t getFirstId() { return getRandomId(); }
27
34 template <typename Vector>
35 static auto getNextId(const Vector& ids)
36 {
37 typename Vector::value_type id{};
38
39 constexpr auto fnd = [](const auto& ids, const auto& id) noexcept {
40 for(auto& elt : ids)
41 if(elt == id)
42 return true;
43 return false;
44 };
45
46 do
47 {
48 id = typename Vector::value_type{getRandomId()};
49 } while(fnd(ids, id));
50
51 return id;
52 }
53};
54
58struct SCORE_LIB_BASE_EXPORT linear_id_generator
59{
60 static int32_t getFirstId() { return 1; }
61
62 template <typename Vector>
63 static auto getNextId(const Vector& ids)
64 {
65 auto it = std::max_element(ids.begin(), ids.end());
66 if(it != ids.end())
67 return typename Vector::value_type{getId(*it) + 1};
68 else
69 return typename Vector::value_type{getFirstId()};
70 }
71
72private:
73 template <typename T>
74 static int32_t getId(const Id<T>& other)
75 {
76 return other.val();
77 }
78 static int32_t getId(const std::optional<int32_t>& i) { return *i; }
79 static int32_t getId(int32_t i) { return i; }
80};
81
83}
84template <typename T>
85auto getStrongId(const std::vector<Id<T>>& v)
86{
87 return Id<T>{score::id_generator::getNextId(v)};
88}
89
90template <typename T>
91auto getStrongId(const score::dynvector_impl<Id<T>>& v)
92{
93 return Id<T>{score::id_generator::getNextId(v)};
94}
95
96template <typename Container>
97 requires(std::is_pointer<typename Container::value_type>::value)
98auto getStrongId(const Container& v)
100{
101 using namespace std;
102 using local_id_t
104 vector<int32_t> ids(v.size()); // Map reduce
105
106 transform(
107 v.begin(), v.end(), ids.begin(),
108 [](const typename Container::value_type& elt) { return elt->id().val(); });
109
110 return local_id_t{score::id_generator::getNextId(ids)};
111}
112
113template <typename Container>
114 requires(!std::is_pointer<typename Container::value_type>::value)
115auto getStrongId(const Container& v) -> Id<typename Container::value_type>
116{
117 using namespace std;
118 auto ids = make_dynarray(int32_t, v.size());
119
120 transform(
121 v.begin(), v.end(), ids.begin(), [](const auto& elt) { return elt.id().val(); });
122
123 return Id<typename Container::value_type>{score::id_generator::getNextId(ids)};
124}
125
126template <typename T>
127auto getStrongIdRange(std::size_t s)
128{
129 std::vector<Id<T>> vec;
130 vec.reserve(s);
131 vec.emplace_back(score::id_generator::getFirstId());
132
133 s--;
134 for(std::size_t i = 0; i < s; i++)
135 {
136 vec.push_back(getStrongId(vec));
137 }
138
139 return vec;
140}
141
142template <typename T, typename Vector>
143auto getStrongIdRange(std::size_t s, const Vector& existing)
144{
145 auto existing_size = existing.size();
146 auto total_size = existing_size + s;
147 std::vector<Id<T>> vec;
148 vec.reserve(total_size);
149
150 // Copy the existing ids
151 std::transform(
152 existing.begin(), existing.end(), std::back_inserter(vec),
153 [](const auto& elt) { return elt.id(); });
154
155 // Then generate the new ones
156 for(std::size_t i = 0; i < s; i++)
157 {
158 vec.push_back(getStrongId(vec));
159 }
160
161 return std::vector<Id<T>>(vec.begin() + existing.size(), vec.end());
162}
163
164template <typename T, typename Vector1, typename Vector2>
165static auto
166getStrongIdRange2(std::size_t s, const Vector1& existing1, const Vector2& existing2)
167{
168 std::vector<Id<T>> vec;
169 vec.reserve(s + existing1.size() + existing2.size());
170 std::transform(
171 existing1.begin(), existing1.end(), std::back_inserter(vec),
172 [](const auto& elt) { return elt.id(); });
173 std::transform(
174 existing2.begin(), existing2.end(), std::back_inserter(vec),
175 [](const auto& elt) { return elt->id(); });
176
177 for(std::size_t i = 0; i < s; i++)
178 {
179 vec.push_back(getStrongId(vec));
180 }
181 auto final
182 = std::vector<Id<T>>(vec.begin() + existing1.size() + existing2.size(), vec.end());
183
184 return final;
185}
186
187template <typename T, typename Vector>
188auto getStrongIdRangePtr(std::size_t s, const Vector& existing)
189{
190 std::vector<Id<T>> vec;
191 vec.reserve(s + existing.size());
192 std::transform(
193 existing.begin(), existing.end(), std::back_inserter(vec),
194 [](const auto& elt) { return elt->id(); });
195
196 for(; s-- > 0;)
197 {
198 vec.push_back(getStrongId(vec));
199 }
200
201 return std::vector<Id<T>>(vec.begin() + existing.size(), vec.end());
202}
The id_base_t class.
Definition Identifier.hpp:57
Definition ArrayView.hpp:56
Base toolkit upon which the software is built.
Definition Application.cpp:97
STL namespace.
Generates identifiers for new objects, starting from 1.
Definition IdentifierGeneration.hpp:59
Generates random identifiers for new objects.
Definition IdentifierGeneration.hpp:20
static auto getNextId(const Vector &ids)
getNextId
Definition IdentifierGeneration.hpp:35