|
|
- #pragma once
-
- #include <gp/algorithms/move.hpp>
- #include <gp/functional/function.hpp>
- #include <gp/exception.hpp>
- #include <gp/utils/iterator.hpp>
- #include <gp/functional/optional.hpp>
-
- #include <cstddef>
- #include <cstdint>
-
- namespace gp{
-
- template<typename T>
- class buffer final{
- public:
- private:
- pointer_iterator<T> begin_elem;
- pointer_iterator<T> end_elem;
-
-
- static constexpr size_t local_strlen(const char* str) {
- auto ptr = str;
- do{}while(*(ptr++));
- return ptr-str-1;
- }
-
- public:
- using associated_iterator = pointer_iterator<T>;
-
- constexpr buffer(const char* val) requires std::is_same_v<T, char>
- : begin_elem{const_cast<char*>(val)}
- , end_elem{const_cast<char*>(val)+local_strlen(val)}
- {}
-
- constexpr buffer(T* beg_ptr, T* end_ptr)
- : begin_elem{beg_ptr}
- , end_elem{end_ptr}
- {}
-
- constexpr buffer(associated_iterator beg_ptr, associated_iterator end_ptr)
- : begin_elem{beg_ptr}
- , end_elem{end_ptr}
- {}
-
- constexpr buffer(T* beg_ptr, std::size_t sz)
- : begin_elem{beg_ptr}
- , end_elem{beg_ptr+sz}
- {}
-
- constexpr typename pointer_iterator<T>::difference_type size() const
- {
- return end_elem - begin_elem;
- }
-
- constexpr associated_iterator begin() const
- {
- return begin_elem;
- }
-
- constexpr associated_iterator end() const
- {
- return end_elem;
- }
-
- constexpr T& operator[](std::size_t offset)
- {
- if constexpr (gp_config::has_buffer_bounds)
- {
- gp_config::assertion(
- offset < size(),
- "Buffer bounds infringed"
- );
- }
- return *(begin_elem+offset);
- }
-
- constexpr const T& operator[](std::size_t offset) const
- {
- if constexpr (gp_config::has_buffer_bounds)
- {
- gp_config::assertion(
- offset < size(),
- "Buffer bounds infringed"
- );
- }
- return *(begin_elem+offset);
- }
-
- optional<pointer_iterator<T>> at(std::size_t offset)
- {
- auto elem = begin()+offset;
- if(!contains(elem))
- {
- return nullopt;
- }
- return elem;
- }
-
- constexpr bool contains(pointer_iterator<T> ptr)
- {
- return
- ptr.data < end_elem.data
- && ptr.data >= begin_elem.data;
- }
-
- template<typename U>
- buffer<U> cast()
- {
- if constexpr(sizeof(T)%sizeof(U) == 0)
- {
- return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*(sizeof(T)/sizeof(U)));
- }
- else
- {
- if((size()*sizeof(T))%sizeof(U) == 0)
- {
- return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*sizeof(T)/sizeof(U));
- }
- else if constexpr (gp_config::has_exceptions)
- {
- throw bad_buffer_cast<T, U>{};
- }
- else
- {
- return buffer<U>(reinterpret_cast<U*>(nullptr), 0);
- }
- }
- }
-
- buffer slice_start(size_t new_sz)
- {
- if(new_sz<=size())
- {
- return buffer{&*begin(), &*(begin()+new_sz)};
- }
- else
- {
- return buffer{(T*)nullptr,(size_t)0};
- }
- }
-
- buffer slice_end(size_t new_sz)
- {
- if(new_sz<=size())
- {
- return buffer{&*(end()-(new_sz)), &*end()};
- }
- else
- {
- return buffer{(T*)nullptr,(size_t)0};
- }
- }
-
- buffer trim_start(size_t rm_sz)
- {
- if(rm_sz<=size())
- {
- return buffer{begin().data + rm_sz, end().data};
- }
- else
- {
- return buffer{(T*)nullptr,(size_t)0};
- }
- }
-
- buffer trim_end(size_t rm_sz)
- {
- if(rm_sz<=size())
- {
- return buffer{begin().data, end().data - rm_sz};
- }
- else
- {
- return buffer{(T*)nullptr,(size_t)0};
- }
- }
- };
- }
|