Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <cstdint>
- #include <cstring>
- #include <cstdio>
- template<class SrcType, class TargetType>
- struct copy_constness_t
- {
- typedef typename std::conditional<std::is_const<SrcType>::value,const TargetType,TargetType>::type type;
- };
- template<class ValueType>
- class slice_T
- {
- public:
- typedef ValueType value_type;
- explicit slice_T(ValueType* const p_begin, const std::size_t& p_size):
- m_begin(p_begin),
- m_size(p_size)
- {
- }
- explicit slice_T(typename copy_constness_t<ValueType, void>::type* const p_begin, const std::size_t& p_size):
- m_begin(reinterpret_cast<ValueType*>(p_begin)),
- m_size(p_size)
- {
- }
- template<class Other>
- explicit slice_T(const Other& p_other):
- m_begin(p_other.begin()),
- m_size(p_other.size())
- {
- }
- std::size_t size() const
- {
- return m_size;
- }
- //const or non const based on ValueType
- ValueType* const begin() const
- {
- return m_begin;
- }
- //const or non const based on ValueType
- ValueType* const end() const
- {
- return m_begin+m_size;
- }
- /*
- //const in any way
- const ValueType* const const_begin() const
- {
- return begin();
- }
- //const in any way
- const ValueType* const const_end() const
- {
- return end();
- }
- std::size_t byte_size() const
- {
- return m_size * sizeof(ValueType);
- }
- //same slice?
- template<class Other>
- bool operator ==(const Other& p_other) const
- {
- static_assert(sizeof(typename Other::value_type) == sizeof(value_type),"not equal size type");
- //Other muss passende size() und begin() definieren
- return
- m_begin == p_other.begin()
- && size() == p_other.size();
- }
- template<class Other>
- bool operator !=(const Other& p_other) const
- {
- return !operator==(p_other);
- }
- //same content?
- template<class Other>
- bool equal(const Other& p_other) const
- {
- static_assert(sizeof(typename Other::value_type) == sizeof(value_type),"not equal size type");
- //Other muss passende size() und begin() definieren
- return
- size() == p_other.size()
- && ( m_begin == p_other.begin() || ::memcmp(begin(), p_other.begin(), byte_size()) == 0 );
- }
- void enough_space_left_at(const size_t& p_offset, const size_t& p_count) const
- {
- if( p_count > left_at(p_offset) ) throw 1;
- }
- template<class SliceValueType>
- slice_T<SliceValueType> get_slice(const size_t& p_offset, const size_t& p_size) const
- {
- enough_space_left_at(p_offset, p_size);
- return slice_T<SliceValueType>(begin()+p_offset, p_size);
- }
- slice_T<ValueType> slice(const size_t& p_offset, const size_t& p_size) const
- {
- return get_slice<ValueType>(p_offset, p_size);
- }
- slice_T<const ValueType> const_slice(const size_t& p_offset, const size_t& p_size) const
- {
- return get_slice<const ValueType>(p_offset, p_size);
- }
- size_t left_at(const size_t& p_offset) const
- {
- return size() - p_offset;
- }
- //assigne operator
- slice_T<ValueType>& operator=(const slice_T<ValueType>& p_other)
- {
- if (this != &p_other)
- {
- m_size = p_other.size();
- m_begin = p_other.begin();
- }
- return *this;
- }
- //copy ctor
- slice_T(const slice_T<ValueType>& p_other):
- m_begin(p_other.begin()),
- m_size(p_other.size())
- {
- }
- */
- private:
- ValueType* const m_begin;
- size_t m_size;
- };
- template<class SliceType>
- class binary_reader_t
- {
- public:
- static_assert(sizeof(typename SliceType::value_type) == sizeof(std::uint8_t), "only uint8_t like slices allowed");
- explicit binary_reader_t(const SliceType& p_slice):
- m_slice(p_slice),
- m_offset(0)
- {
- }
- std::size_t left() const
- {
- return m_slice.size() - m_offset;
- }
- //copy constness of slice
- template<class TargetType>
- struct ref_type_t
- {
- typedef typename copy_constness_t<typename SliceType::value_type,TargetType>::type type;
- };
- void enough_space_left(const size_t& p_size) const
- {
- if( p_size > left() ) throw 1;
- }
- //ref
- template<class ValueType>
- typename ref_type_t<ValueType>::type& read_ref()
- {
- enough_space_left(sizeof(ValueType));
- typename ref_type_t<ValueType>::type& ref = *reinterpret_cast<typename ref_type_t<ValueType>::type*>(m_slice.begin()+m_offset);
- m_offset += sizeof(ValueType);
- return ref;
- }
- //copy
- template<class ValueType>
- typename ref_type_t<ValueType>::type read_value()
- {
- return read_ref<ValueType>();
- }
- private:
- SliceType m_slice;
- size_t m_offset;
- };
- int main()
- {
- try
- {
- const uint8_t TEST_DATA[] = "THIS IS BINARY TEST DATA"; // immutable data
- const slice_T<const std::uint8_t> test_slice(TEST_DATA, sizeof(TEST_DATA));
- typedef binary_reader_t<slice_T<const std::uint8_t>> stream_t;
- static_assert(std::is_const<stream_t::ref_type_t<std::uint32_t>::type>::value, "not const");
- stream_t stream(test_slice);
- const std::uint32_t& ref = stream.read_ref<std::uint32_t>();
- const std::uint32_t value = stream.read_value<std::uint32_t>();
- }
- catch(const int& p_error)
- {
- printf("exception error: %i\n", p_error);
- }
- catch(...)
- {
- printf("exception unknown\n");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement