General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #pragma once
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <gp/optional.hpp>
  5. #include <gp/iterator.hpp>
  6. #include <gp/function.hpp>
  7. #include <gp/exception.hpp>
  8. #include <gp/algorithm/move.hpp>
  9. namespace gp{
  10. template<typename T>
  11. class buffer final{
  12. public:
  13. private:
  14. pointer_iterator<T> begin_elem;
  15. pointer_iterator<T> end_elem;
  16. public:
  17. using associated_iterator = pointer_iterator<T>;
  18. constexpr buffer(T* beg_ptr, T* end_ptr)
  19. : begin_elem{beg_ptr}
  20. , end_elem{end_ptr}
  21. {}
  22. constexpr buffer(T* beg_ptr, std::size_t sz)
  23. : begin_elem{beg_ptr}
  24. , end_elem{beg_ptr+sz}
  25. {}
  26. constexpr typename pointer_iterator<T>::difference_type size() const
  27. {
  28. return end_elem - begin_elem;
  29. }
  30. constexpr associated_iterator begin() const
  31. {
  32. return begin_elem;
  33. }
  34. constexpr associated_iterator end() const
  35. {
  36. return end_elem;
  37. }
  38. constexpr T& operator[](std::size_t offset)
  39. {
  40. return *(begin_elem+offset);
  41. }
  42. optional<pointer_iterator<T>> at(std::size_t offset)
  43. {
  44. auto elem = begin()+offset;
  45. if(!contains(elem))
  46. {
  47. return nullopt;
  48. }
  49. return elem;
  50. }
  51. constexpr bool contains(pointer_iterator<T> ptr)
  52. {
  53. return
  54. ptr.data < end_elem.data
  55. && ptr.data >= begin_elem.data;
  56. }
  57. template<typename U>
  58. buffer<U> cast()
  59. {
  60. if constexpr(sizeof(T)%sizeof(U) == 0)
  61. {
  62. return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*(sizeof(T)/sizeof(U)));
  63. }
  64. else
  65. {
  66. if(size()*sizeof(T)/sizeof(U))
  67. {
  68. return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*sizeof(T)/sizeof(U));
  69. }
  70. else if constexpr (gp_config::has_exceptions)
  71. {
  72. throw bad_buffer_cast<T, U>{};
  73. }
  74. else
  75. {
  76. return buffer<U>(reinterpret_cast<U*>(nullptr), 0);
  77. }
  78. }
  79. }
  80. buffer slice_start(size_t new_sz)
  81. {
  82. if(new_sz<=size())
  83. {
  84. return buffer{&*begin(), &*(begin()+new_sz)};
  85. }
  86. else
  87. {
  88. return buffer{(T*)nullptr,(size_t)0};
  89. }
  90. }
  91. buffer slice_end(size_t new_sz)
  92. {
  93. if(new_sz<=size())
  94. {
  95. return buffer{&*(end()-(1+new_sz)), &*end()};
  96. }
  97. else
  98. {
  99. return buffer{(T*)nullptr,(size_t)0};
  100. }
  101. }
  102. };
  103. }