idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
Versions.h
1//
2// Created by henri on 27/01/23.
3//
4
5#ifndef IDOL_VERSIONS_H
6#define IDOL_VERSIONS_H
7
8#include <vector>
9#include <optional>
10#include <any>
11#include "idol/general/utils/exceptions/Exception.h"
12#include "idol/general/utils/Optional.h"
13#include "idol/mixed-integer/modeling/models/Model.h"
14
15namespace idol {
16 class Model;
17
18 template<class T>
19 class Versions;
20}
21
26template<class T>
28 static const unsigned int s_buffer_size = 10;
29
30 std::vector<Optional<T>> m_versions;
31 std::vector<std::any> m_annotations;
32public:
33 template<class ...ArgsT> explicit Versions(ArgsT&& ...t_args) : m_versions({ idol::make_optional<T>(std::forward<ArgsT&&>(t_args)...) }) {}
34
35 Versions(const Versions&) = delete;
36 Versions(Versions&&) noexcept = delete;
37
38 Versions& operator=(const Versions&) = delete;
39 Versions& operator=(Versions&&) noexcept = delete;
40
41 template<class ...ArgsT> void create(const Model& t_model, unsigned int t_index, ArgsT&& ...t_args);
42
43 void remove(const Model& t_model);
44
45 [[nodiscard]] bool has(const Model& t_model) const;
46
47 [[nodiscard]] const T& get(const Model& t_model) const;
48
49 T& get(const Model& t_model);
50
51 [[nodiscard]] const T& get_default() const;
52
53 T& get_default();
54
55 template<class ValueT> const ValueT* get_annotation(unsigned int t_index) const;
56
57 template<class ValueT, class ...ArgsT> void set_annotation(unsigned int t_index, ArgsT&& ...t_args) {
58 if (t_index >= m_annotations.size()) {
59 m_annotations.resize(t_index + s_buffer_size);
60 }
61 m_annotations[t_index] = ValueT(std::forward<ArgsT>(t_args)...);
62 }
63};
64
65template<class T>
66template<class ValueT>
67const ValueT* idol::Versions<T>::get_annotation(unsigned int t_index) const {
68 if (t_index >= m_annotations.size() || !m_annotations[t_index].has_value()) {
69 return nullptr;
70 }
71 return &std::any_cast<const ValueT&>(m_annotations[t_index]);
72}
73
74template<class T>
75const T &idol::Versions<T>::get_default() const {
76 return *m_versions.front();
77}
78
79template<class T>
81 return *m_versions.front();
82}
83
84template<class T>
85template<class ...ArgsT>
86void idol::Versions<T>::create(const Model &t_model, unsigned int t_index, ArgsT&& ...t_args) {
87
88 const unsigned int index = t_model.id();
89
90 if (m_versions.size() <= index) {
91 m_versions.resize(index + s_buffer_size);
92 } else if (m_versions[index].has_value()) {
93 throw Exception("Object already in model.");
94 }
95
96 m_versions[index] = T(t_index, std::forward<ArgsT>(t_args)...);
97}
98
99template<class T>
100const T &idol::Versions<T>::get(const Model &t_model) const {
101 const unsigned int id = t_model.id();
102 if (id >= m_versions.size() || !m_versions[id].has_value()) {
103 throw Exception("Object not part of model.");
104 }
105 return m_versions[id].value();
106}
107
108template<class T>
109T &idol::Versions<T>::get(const Model &t_model) {
110 const unsigned int id = t_model.id();
111 if (id >= m_versions.size() || !m_versions[id].has_value()) {
112 throw Exception("Object not part of model.");
113 }
114 return m_versions[id].value();
115}
116
117template<class T>
118void idol::Versions<T>::remove(const Model &t_model) {
119 if (!has(t_model)) { return; }
120 m_versions[t_model.id()].reset();
121}
122
123template<class T>
124bool idol::Versions<T>::has(const Model &t_model) const {
125 const unsigned int index = t_model.id();
126 return index < m_versions.size() && m_versions[index].has_value();
127}
128
129#endif //IDOL_VERSIONS_H