#ifndef INCLUDE_SHADER_SOURCE_STORE_IMPLEMENTATION # error Never include this file directly include 'shader_source_store.hpp' #endif #include #include #include #include #include #include #include "opengl/metadata/shader_source_metadata.hpp" template assets::shader_source_store_iterator::shader_source_store_iterator( id_iterator_type ids, string_iterator_type strings, length_iterator_type lengths, metadata_iterator_type metadata, std::size_t index, const offset_type& offset ) : m_ids{ ids }, m_strings{ strings }, m_lengths{ lengths }, m_metadata{ metadata }, m_index{ index }, m_offset{ offset } {} template typename assets::shader_source_store_iterator::reference assets::shader_source_store_iterator::operator*() const { return dereference(std::index_sequence_for{}); } template assets::shader_source_store_iterator& assets::shader_source_store_iterator::operator++() { adjust_offsets(std::index_sequence_for{}, 1); ++m_index; return *this; } template assets::shader_source_store_iterator assets::shader_source_store_iterator::operator++(int) { shader_source_store_iterator tmp = *this; ++(*this); return tmp; } template assets::shader_source_store_iterator& assets::shader_source_store_iterator::operator--() { adjust_offsets(std::index_sequence_for{}, -1); --m_index; return *this; } template assets::shader_source_store_iterator assets::shader_source_store_iterator::operator--(int) { auto tmp = *this; --(*this); return tmp; } template assets::shader_source_store_iterator& assets::shader_source_store_iterator::operator+=(const difference_type n) { adjust_offsets(std::index_sequence_for{}, n); m_index += n; return *this; } template assets::shader_source_store_iterator& assets::shader_source_store_iterator::operator-=(const difference_type n) { return (*this) += -n; } template assets::shader_source_store_iterator assets::shader_source_store_iterator::operator+(const difference_type n) const { auto tmp = *this; return tmp += n; // TODO clion says n is unused } template assets::shader_source_store_iterator assets::shader_source_store_iterator::operator-(const difference_type n) const { auto tmp = *this; return tmp -= n; // TODO clion says n is unused } template typename assets::shader_source_store_iterator::difference_type assets::shader_source_store_iterator::operator-(const shader_source_store_iterator& other) const { return static_cast(m_index) - static_cast(other.m_index); } template typename assets::shader_source_store_iterator::reference assets::shader_source_store_iterator::operator[]( const difference_type n ) const { return *(*this + n); } template bool assets::shader_source_store_iterator::operator==(const shader_source_store_iterator& other) const { return m_ids == other.m_ids and m_index == other.m_index; } template bool assets::shader_source_store_iterator::operator!=(const shader_source_store_iterator& other) const { return not (*this == other); } template bool assets::shader_source_store_iterator::operator<(const shader_source_store_iterator& other) const { return m_index < other.m_index; } template bool assets::shader_source_store_iterator::operator<=(const shader_source_store_iterator& other) const { return m_index <= other.m_index; } template bool assets::shader_source_store_iterator::operator>(const shader_source_store_iterator& other) const { return m_index > other.m_index; } template bool assets::shader_source_store_iterator::operator>=(const shader_source_store_iterator& other) const { return m_index >= other.m_index; } template void assets::shader_source_store_iterator::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 assets::shader_source_store_iterator::reference assets::shader_source_store_iterator::dereference() const { return std::make_pair( m_ids[m_index], shader_source_view{ .source = { m_strings[m_offset], m_lengths[m_index] }, .meta = m_metadata[m_index] } ); } assets::shader_source_store::id_type assets::shader_source_store::add( const shader_source_id id, const shader_source_data& shader_source ) { 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()); m_metadata.push_back(shader_source.meta); return id; } std::pair 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::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); m_metadata.erase(m_metadata.begin() + it.m_index); } void assets::shader_source_store::clear() { m_ids.clear(); m_strings.clear(); m_lengths.clear(); m_metadata.clear(); } assets::shader_source_store::iterator_type assets::shader_source_store::begin() { return iterator_type{ m_ids.data(), m_strings.data(), m_lengths.data(), m_metadata.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_metadata.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(), m_metadata.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_metadata.data(), m_lengths.size(), m_strings.size() }; } assets::shader_source_store::const_iterator assets::shader_source_store::cbegin() const { return this->begin(); } assets::shader_source_store::const_iterator assets::shader_source_store::cend() const { return this->end(); }