#pragma once template typename V::data_type const * ikarus_value_base_get(V * value, size_t idx) { if (auto * data = value->data.template get_if>(); data != nullptr) { return &(*data)[idx]; } return nullptr; } template size_t ikarus_value_base_get_size(V const * value) { if (auto * data = value->data.template get_if>(); data != nullptr) { return data->size(); } return 0; } template void ikarus_value_base_set(V * value, size_t idx, typename V::data_type new_data) { if (auto * data = value->data.template get_if>(); data != nullptr) { (*data)[idx] = new_data; } } template void ikarus_value_base_remove(V * value, size_t idx) { if (auto * data = value->data.template get_if>(); data != nullptr) { data->erase(data->begin() + idx); } } template void ikarus_value_base_insert(V * value, size_t idx, typename V::data_type new_data) { if (auto * data = value->data.template get_if>(); data != nullptr) { data->insert(data->begin() + idx, new_data); } } template void ikarus_value_base_clear(V * value) { if (auto * data = value->data.template get_if>(); data != nullptr) { data->clear(); } } template bool ikarus_value_base_is_undefined(V const * value) { return boost::variant2::holds_alternative(value->data); } template void ikarus_value_base_set_undefined(V * value, bool undefined) { if (undefined) { value->data = boost::variant2::monostate{}; } else { value->data = typename V::data_type{}; } } template bool ikarus_value_base_is_equal(V const * lhs, V const * rhs) { return lhs->data == rhs->data; } template V * ikarus_value_base_copy(V const * value) { return new V{*value}; } template struct IkarusValue * ikarus_value_base_to_value(V * value) { return static_cast(value); } template struct IkarusValue const * ikarus_value_base_to_value_const(V const * value) { return static_cast(value); }