tried making naming more uniform and implemented most of the opengl managers
This commit is contained in:
63
source/assets/data_stores/generic/generic_basic_store.ipp
Normal file
63
source/assets/data_stores/generic/generic_basic_store.ipp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_basic_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
template<typename T>
|
||||
typename generic_basic_store<T>::id_type generic_basic_store<T>::add(const T& data)
|
||||
{
|
||||
auto id = id_type{ m_next_data_id.index++ };
|
||||
m_data.emplace_back(data);
|
||||
m_ids.emplace_back(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::pair<typename generic_basic_store<T>::iterator_type, bool> generic_basic_store<T>::find(id_type id)
|
||||
{
|
||||
const auto it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto found = it != m_ids.begin() and *std::prev(it) == id;
|
||||
const auto index = it - m_ids.begin() - found;
|
||||
|
||||
return { m_data.begin() + index, found };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::pair<typename generic_basic_store<T>::const_iterator, bool> generic_basic_store<T>::find(id_type id) const
|
||||
{
|
||||
const auto it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto found = it != m_ids.begin() and *std::prev(it) == id;
|
||||
const auto index = it - m_ids.begin() - found;
|
||||
|
||||
return { m_data.begin() + index, found };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void generic_basic_store<T>::remove(iterator_type it)
|
||||
{
|
||||
const auto index = it - m_data.begin();
|
||||
m_data.erase(it);
|
||||
m_ids.erase(m_ids.begin() + index);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void generic_basic_store<T>::clear()
|
||||
{
|
||||
m_data.clear();
|
||||
m_ids.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::span<T> generic_basic_store<T>::data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::span<const T> generic_basic_store<T>::data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
#ifndef INCLUDE_GENERIC_DYNAMIC_COMPONENT_ARRAY_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_dynamic_component_array_store.hpp'
|
||||
#endif
|
||||
#include <bits/ranges_algo.h>
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>::component_array_iterator(
|
||||
id_array_pointer_type ids,
|
||||
const component_array_pointer_type& components,
|
||||
flag_count_pointer_type flags,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flags },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_array_iterator<C, Ts...>::reference component_array_iterator<C, Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>& component_array_iterator<C, Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator++(int) {
|
||||
component_array_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>& component_array_iterator<C, Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>& component_array_iterator<C, Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>& component_array_iterator<C, Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_array_iterator<C, Ts...>::difference_type
|
||||
component_array_iterator<C, Ts...>::operator-(const component_array_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_array_iterator<C, Ts...>::reference component_array_iterator<C, Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *((*this) + n);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator==(const component_array_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator!=(const component_array_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator<(const component_array_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator<=(const component_array_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator>(const component_array_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator>=(const component_array_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t I>
|
||||
bool component_array_iterator<C, Ts...>::is_component_enabled(C flag)
|
||||
{
|
||||
return (flag & (C{1} << I)) != C{};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void component_array_iterator<C, Ts...>::calc_offsets(std::index_sequence<Is...>, difference_type n)
|
||||
{
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, count ] = m_flag_counts[m_index];
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<Is>(m_offsets) += step * count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename component_array_iterator<C, Ts...>::reference
|
||||
component_array_iterator<C, Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
std::make_tuple(
|
||||
flags,
|
||||
std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_component_array_store<C, Ts...>::component_array_ptrs()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> generic_dynamic_component_array_store<C, Ts...>::component_array_ptrs() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::array<std::size_t, sizeof...(Ts)> generic_dynamic_component_array_store<C, Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{ std::get<Is>(m_component_arrays).size()... };
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::id_type generic_dynamic_component_array_store<C, Ts...>::add(
|
||||
const std::tuple<std::vector<Ts>...>& component_arrays
|
||||
) {
|
||||
|
||||
auto component_flags = C{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(component_arrays);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= C{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(component_arrays);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.emplace_back(component_flags, min_component_count);
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::pair<typename generic_dynamic_component_array_store<C, Ts...>::iterator_type, bool> generic_dynamic_component_array_store<C, Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::pair<typename generic_dynamic_component_array_store<C, Ts...>::const_iterator, bool> generic_dynamic_component_array_store<C, Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void generic_dynamic_component_array_store<C, Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void generic_dynamic_component_array_store<C, Ts...>::clear()
|
||||
{
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
m_ids.clear();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::iterator_type generic_dynamic_component_array_store<C, Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::iterator_type generic_dynamic_component_array_store<C, Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::begin() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::end() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_component_array_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_component_array_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::view_type generic_dynamic_component_array_store<C, Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_view_type generic_dynamic_component_array_store<C, Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
#ifndef INCLUDE_GENERIC_DYNAMIC_INDEXED_COMPONENT_ARRAY_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_dynamic_indexed_component_array_store.hpp'
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>::indexed_component_array_iterator(
|
||||
id_array_pointer_type ids,
|
||||
const index_array_pointer_type indices,
|
||||
const component_array_pointer_type& components,
|
||||
const flag_count_pointer_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_indices{ indices },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename indexed_component_array_iterator<C, I, Ts...>::reference indexed_component_array_iterator<C, I, Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>& indexed_component_array_iterator<C, I, Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator++(int) {
|
||||
indexed_component_array_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>& indexed_component_array_iterator<C, I, Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>& indexed_component_array_iterator<C, I, Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>& indexed_component_array_iterator<C, I, Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename indexed_component_array_iterator<C, I, Ts...>::difference_type
|
||||
indexed_component_array_iterator<C, I, Ts...>::operator-(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename indexed_component_array_iterator<C, I, Ts...>::reference indexed_component_array_iterator<C, I, Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator==(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator!=(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator<(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator<=(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator>(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator>=(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::is_component_enabled(C flag)
|
||||
{
|
||||
return (flag & (C{1} << N)) != C{};
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void indexed_component_array_iterator<C, I, Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename indexed_component_array_iterator<C, I, Ts...>::reference
|
||||
indexed_component_array_iterator<C, I, Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
std::make_tuple(
|
||||
flags,
|
||||
std::span(
|
||||
m_indices[m_offsets[0]],
|
||||
index_count
|
||||
),
|
||||
std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_indexed_component_array_store<C, I, Ts...>::component_array_ptrs()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> generic_dynamic_indexed_component_array_store<C, I, Ts...>::component_array_ptrs() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::array<std::size_t, 1 + sizeof...(Ts)> generic_dynamic_indexed_component_array_store<C, I, Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
m_indices.size(),
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::id_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::add(
|
||||
std::span<const I> indices,
|
||||
const std::tuple<std::vector<Ts>...>& component_arrays
|
||||
) {
|
||||
|
||||
auto component_flags = C{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(component_arrays);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= C{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_indices.insert(m_indices.end(), indices.begin(), indices.end());
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(component_arrays);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.emplace_back(component_flags, indices.size(), min_component_count);
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::pair<typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::iterator_type, bool> generic_dynamic_indexed_component_array_store<C, I,Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::pair<typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator, bool> generic_dynamic_indexed_component_array_store<C, I,Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
void generic_dynamic_indexed_component_array_store<C, I,Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
m_indices.erase(m_indices.begin() + it.m_offsets[0]);
|
||||
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
void generic_dynamic_indexed_component_array_store<C, I,Ts...>::clear()
|
||||
{
|
||||
m_indices.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
m_ids.clear();
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::iterator_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::iterator_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::begin() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::end() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_indexed_component_array_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_indexed_component_array_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::view_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_view_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
386
source/assets/data_stores/generic/generic_material_store.ipp
Normal file
386
source/assets/data_stores/generic/generic_material_store.ipp
Normal file
@@ -0,0 +1,386 @@
|
||||
#ifndef INCLUDE_GENERIC_MATERIAL_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_material_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>::generic_material_store_iterator(
|
||||
id_iterator_type ids,
|
||||
const component_iterator_type& components,
|
||||
flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference assets::detail::generic_material_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator++(int) {
|
||||
generic_material_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_material_store_iterator<Ts...>::operator-(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference assets::detail::generic_material_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator==(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator!=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator<(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator<=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator>(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator>=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_material_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_material_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& flags = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
material_view{
|
||||
.data = {
|
||||
(
|
||||
is_component_enabled<Is>(flags)
|
||||
? std::optional{ std::get<Is>(m_components)[m_offsets[Is]] }
|
||||
: std::nullopt
|
||||
)...
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_material_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_material_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::id_type assets::detail::generic_material_store<Ts...>::add(
|
||||
const material_data& material
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
if (const auto& component_opt = std::get<Is>(material.data))
|
||||
{
|
||||
std::get<Is>(material.data).push_back(*component_opt);
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.push_back(component_flags);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_material_store<Ts...>::iterator_type, bool> assets::detail::generic_material_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_material_store<Ts...>::const_iterator, bool> assets::detail::generic_material_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_material_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
(component_vector.erase(component_vector.begin() + it.m_offsets[Is]), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_material_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_material_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_material_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::view_type assets::detail::generic_material_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_view_type assets::detail::generic_material_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
449
source/assets/data_stores/generic/generic_mesh_store.ipp
Normal file
449
source/assets/data_stores/generic/generic_mesh_store.ipp
Normal file
@@ -0,0 +1,449 @@
|
||||
#ifndef INCLUDE_GENERIC_MESH_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_mesh_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
|
||||
id_iterator_type ids,
|
||||
index_iterator_type indices,
|
||||
const component_iterator_type& components,
|
||||
material_id_iterator_type material_ids,
|
||||
flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_indices{ indices },
|
||||
m_components{ components },
|
||||
m_material_ids{ material_ids },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference assets::detail::generic_mesh_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator++(int) {
|
||||
generic_mesh_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::operator-(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference assets::detail::generic_mesh_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator==(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator!=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator<(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator<=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator>(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator>=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_mesh_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
mesh_view{
|
||||
.component_flags = flags,
|
||||
.indices = std::span(
|
||||
m_indices[m_offsets[0]],
|
||||
index_count
|
||||
),
|
||||
.vertex_component_arrays = std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
.material_id = m_material_ids[m_index]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_mesh_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_mesh_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
m_indices.size(),
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::id_type assets::detail::generic_mesh_store<Ts...>::add(
|
||||
const mesh_data& mesh
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
const auto& vertices = mesh.vertices;
|
||||
const auto& triangles = mesh.triangles();
|
||||
const auto indices = std::span(triangles.front().data(), triangles.size() * 3);
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
// finding out correct component flags and count
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(vertices);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert indices
|
||||
m_indices.insert(m_indices.end(), indices.begin(), indices.end());
|
||||
|
||||
// Insert vertex components
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(vertices);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert material
|
||||
m_material_ids.emplace_back(mesh.material_id());
|
||||
|
||||
// TODO check count
|
||||
m_component_flag_counts.emplace_back(
|
||||
mesh.component_flags,
|
||||
static_cast<count_type>(indices.size()),
|
||||
min_component_count
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_mesh_store<Ts...>::iterator_type, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_mesh_store<Ts...>::const_iterator, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_mesh_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
m_indices.erase(m_indices.begin() + it.m_offsets[0]);
|
||||
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_material_ids.erase(m_material_ids.begin() + it.m_index);
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_mesh_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
m_indices.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
m_material_ids.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_mesh_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_mesh_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::view_type assets::detail::generic_mesh_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_view_type assets::detail::generic_mesh_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
415
source/assets/data_stores/generic/generic_point_cloud_store.ipp
Normal file
415
source/assets/data_stores/generic/generic_point_cloud_store.ipp
Normal file
@@ -0,0 +1,415 @@
|
||||
#ifndef INCLUDE_GENERIC_POINT_CLOUD_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_point_cloud_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::generic_point_cloud_store_iterator(
|
||||
id_iterator_type ids,
|
||||
const component_iterator_type& components,
|
||||
const flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference assets::detail::generic_point_cloud_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator++(int) {
|
||||
generic_point_cloud_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference assets::detail::generic_point_cloud_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator==(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator!=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator<(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator<=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator>(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator>=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_point_cloud_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
point_cloud_view{
|
||||
.vertex_components = flags,
|
||||
.vertex_component_arrays = std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_point_cloud_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_point_cloud_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::id_type assets::detail::generic_point_cloud_store<Ts...>::add(
|
||||
const point_cloud_data& point_cloud
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
const auto& vertices = point_cloud.vertices;
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
// finding out correct component flags and count
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(vertices);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert vertex components
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(vertices);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// TODO check count
|
||||
m_component_flag_counts.emplace_back(
|
||||
point_cloud.component_flags,
|
||||
min_component_count
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_point_cloud_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_point_cloud_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_point_cloud_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_point_cloud_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::view_type assets::detail::generic_point_cloud_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_view_type assets::detail::generic_point_cloud_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
303
source/assets/data_stores/shader_source_store.ipp
Normal file
303
source/assets/data_stores/shader_source_store.ipp
Normal file
@@ -0,0 +1,303 @@
|
||||
#ifndef INCLUDE_SHADER_SOURCE_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'shader_source_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>::shader_source_store_iterator(
|
||||
id_iterator_type ids,
|
||||
string_iterator_type strings,
|
||||
length_iterator_type lengths,
|
||||
std::size_t index,
|
||||
const offset_type& offset
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_strings{ strings },
|
||||
m_lengths{ lengths },
|
||||
m_index{ index },
|
||||
m_offset{ offset } {}
|
||||
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::reference assets::shader_source_store_iterator<Char>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Char>{});
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator++(int) {
|
||||
shader_source_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::difference_type
|
||||
assets::shader_source_store_iterator<Char>::operator-(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::reference assets::shader_source_store_iterator<Char>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator==(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator!=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator<(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator<=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator>(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator>=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
void assets::shader_source_store_iterator<Char>::calc_offset(
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& count = m_lengths[m_index];
|
||||
m_offset += step * count;
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
template<std::size_t... Is>
|
||||
typename assets::shader_source_store_iterator<Char>::reference
|
||||
assets::shader_source_store_iterator<Char>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
shader_source_view(
|
||||
m_strings[m_offset],
|
||||
m_lengths[m_index]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
assets::shader_source_store::id_type assets::shader_source_store::add(
|
||||
const shader_source_data& shader_source
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
m_strings.reserve(m_strings.size() + shader_source.source.size() + 1);
|
||||
m_strings.insert(m_strings.end(), shader_source.source.begin(), shader_source.source.end());
|
||||
m_strings.push_back('\0');
|
||||
|
||||
m_lengths.push_back(shader_source.source.size());
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::pair<assets::shader_source_store::iterator_type, bool> assets::shader_source_store::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
void assets::shader_source_store::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
const auto begin = m_strings.begin() + it.m_offset;
|
||||
const auto end = begin + it.m_lengths[it.m_index];
|
||||
m_strings.erase(begin, end);
|
||||
|
||||
m_lengths.erase(m_lengths.begin() + it.m_index);
|
||||
}
|
||||
|
||||
void assets::shader_source_store::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
m_strings.clear();
|
||||
m_lengths.clear();
|
||||
}
|
||||
|
||||
assets::shader_source_store::iterator_type assets::shader_source_store::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::iterator_type assets::shader_source_store::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
m_lengths.size(),
|
||||
m_strings.size()
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
m_lengths.size(),
|
||||
m_strings.size()
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::cbegin() const
|
||||
{
|
||||
return const_cast<const shader_source_store*>(this)->begin();
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::cend() const
|
||||
{
|
||||
return const_cast<const shader_source_store*>(this)->end();
|
||||
}
|
||||
|
||||
assets::shader_source_store::view_type assets::shader_source_store::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_view_type assets::shader_source_store::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
Reference in New Issue
Block a user