|
|
- #pragma once
- #include <cstddef>
- #include <cstdint>
- #include <gp/optional.hpp>
- #include <gp/iterator.hpp>
- #include <gp/function.hpp>
- #include <gp/exception.hpp>
- #include <gp/algorithm/move.hpp>
-
- namespace gp{
-
- template<typename T>
- class buffer final{
- public:
- struct buffer_iterator final
- {
- T* data;
- typedef T value_type;
- typedef std::size_t difference_type;
- static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator;
-
- constexpr buffer_iterator(const buffer_iterator& oth)
- : data{oth.data}
- {}
-
- constexpr buffer_iterator(T* ptr)
- : data{ptr}
- {}
-
- constexpr operator T&()
- {
- return *data;
- }
-
- constexpr T& operator*(){
- return *data;
- }
-
- constexpr buffer_iterator operator++()
- {
- return buffer_iterator{++data};
- }
-
- constexpr buffer_iterator operator++(int)
- {
- return buffer_iterator{data++};
- }
-
- constexpr buffer_iterator operator--()
- {
- return buffer_iterator{--data};
- }
-
- constexpr buffer_iterator operator--(int)
- {
- return buffer_iterator{data--};
- }
-
- constexpr buffer_iterator operator+(const std::size_t offset)
- {
- return buffer_iterator{data+offset};
- }
-
- constexpr buffer_iterator operator+(const int offset)
- {
- return buffer_iterator{data+offset};
- }
-
- constexpr buffer_iterator operator-(const std::size_t offset)
- {
- return buffer_iterator{data-offset};
- }
-
- constexpr buffer_iterator operator-(const int offset)
- {
- return buffer_iterator{data-offset};
- }
-
- constexpr difference_type operator-(const buffer_iterator& oth) const
- {
- return (T*)data-(T*)oth.data;
- }
-
- constexpr bool operator==(const buffer_iterator& oth)
- {
- return data==oth.data;
- }
-
- constexpr bool operator!=(buffer_iterator& oth)
- {
- return data!=oth.data;
- }
-
- constexpr bool before_or_equal(const buffer_iterator& oth)
- {
- return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
- }
-
- constexpr bool operator<=(const buffer_iterator& oth)
- {
- return before_or_equal(oth);
- }
- };
- private:
- buffer_iterator begin_elem;
- buffer_iterator end_elem;
- public:
- using associated_iterator = buffer_iterator;
-
- constexpr buffer(T* beg_ptr, T* 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 buffer_iterator::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)
- {
- return *(begin_elem+offset);
- }
-
- optional<buffer_iterator> at(std::size_t offset)
- {
- auto elem = begin()+offset;
- if(!contains(elem))
- {
- return nullopt;
- }
- return elem;
- }
-
- constexpr bool contains(buffer_iterator 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))
- {
- 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()-(1+new_sz)), &*end()};
- }
- else
- {
- return buffer{(T*)nullptr,(size_t)0};
- }
- }
- };
- }
|