11#include "idol/general/utils/exceptions/Exception.h" 
   12#include "idol/general/utils/Optional.h" 
   13#include "idol/mixed-integer/modeling/models/Model.h" 
   28    static const unsigned int s_buffer_size = 10;
 
   30    std::vector<Optional<T>> m_versions; 
 
   31    std::vector<std::any> m_annotations;
 
   33    template<
class ...ArgsT> 
explicit Versions(ArgsT&& ...t_args) : m_versions({ idol::make_optional<T>(std::forward<ArgsT&&>(t_args)...) }) {}
 
   41    template<
class ...ArgsT> 
void create(
const Model& t_model, 
unsigned int t_index, ArgsT&& ...t_args);
 
   43    void remove(
const Model& t_model);
 
   45    [[nodiscard]] 
bool has(
const Model& t_model) 
const;
 
   47    [[nodiscard]] 
const T& get(
const Model& t_model) 
const;
 
   49    T& get(
const Model& t_model);
 
   51    [[nodiscard]] 
const T& get_default() 
const;
 
   55    template<
class ValueT> 
const ValueT* get_annotation(
unsigned int t_index) 
const;
 
   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);
 
   61        m_annotations[t_index] = ValueT(std::forward<ArgsT>(t_args)...);
 
 
   68    if (t_index >= m_annotations.size() || !m_annotations[t_index].has_value()) {
 
   71    return &std::any_cast<const ValueT&>(m_annotations[t_index]);
 
   76    return *m_versions.front();
 
   81    return *m_versions.front();
 
   85template<
class ...ArgsT>
 
   88    const unsigned int index = t_model.id();
 
   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.");
 
   96    m_versions[index] = T(t_index, std::forward<ArgsT>(t_args)...);
 
  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.");
 
  105    return m_versions[id].value();
 
  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.");
 
  114    return m_versions[id].value();
 
  119    if (!has(t_model)) { 
return; }
 
  120    m_versions[t_model.id()].reset();
 
  125    const unsigned int index = t_model.id();
 
  126    return index < m_versions.size() && m_versions[index].has_value();