buffer.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #include <types/allocator.hpp>
  3. #include <types/stdint.h>
  4. namespace types {
  5. template <template <typename> class Allocator>
  6. class buffer {
  7. public:
  8. using allocator_type = Allocator<char>;
  9. private:
  10. char* const start;
  11. char* const end;
  12. char* base;
  13. char* head;
  14. size_t count;
  15. private:
  16. constexpr char _get_char(void)
  17. {
  18. --count;
  19. return *base;
  20. }
  21. constexpr void _put_char(char c)
  22. {
  23. *head = c;
  24. ++count;
  25. }
  26. constexpr void _forward(char*& ptr)
  27. {
  28. if (ptr == end)
  29. ptr = start;
  30. else
  31. ++ptr;
  32. }
  33. public:
  34. constexpr buffer(size_t size)
  35. : start { types::allocator_traits<allocator_type>::allocate(size) }
  36. , end { start + size - 1 }
  37. , base { start }
  38. , head { start }
  39. , count { 0 }
  40. {
  41. }
  42. constexpr buffer(const buffer& buf)
  43. : start { types::allocator_traits<allocator_type>::allocate(buf.end + 1 - buf.start) }
  44. , end { start + buf.end - buf.start }
  45. , base { start + buf.base - buf.start }
  46. , head { start + buf.base - buf.start }
  47. , count { buf.count }
  48. {
  49. }
  50. constexpr buffer(buffer&& buf)
  51. : start { buf.start }
  52. , end { buf.end }
  53. , base { buf.base }
  54. , head { buf.head }
  55. , count { buf.count }
  56. {
  57. }
  58. constexpr ~buffer()
  59. {
  60. if (start)
  61. types::allocator_traits<allocator_type>::deallocate(start);
  62. }
  63. constexpr bool empty(void) const
  64. {
  65. return count == 0;
  66. }
  67. constexpr bool full(void) const
  68. {
  69. return count == static_cast<size_t>(end - start + 1);
  70. }
  71. constexpr char get(void)
  72. {
  73. // TODO: set error flag
  74. if (empty())
  75. return 0xff;
  76. char c = _get_char();
  77. _forward(base);
  78. return c;
  79. }
  80. constexpr char put(char c)
  81. {
  82. // TODO: set error flag
  83. if (full())
  84. return 0xff;
  85. _put_char(c);
  86. _forward(head);
  87. return c;
  88. }
  89. };
  90. } // namespace types