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.

159 lines
2.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #pragma once
  2. #include <initializer_list>
  3. #include <gp/buffer.hpp>
  4. namespace gp{
  5. template<typename T, std::size_t sz>
  6. class array{
  7. public:
  8. T ary[sz];
  9. using associated_iterator = pointer_iterator<T, 1>;
  10. using associated_const_iterator = const_pointer_iterator<T, 1>;
  11. using associated_riterator = pointer_iterator<T, -1>;
  12. using associated_const_riterator = const_pointer_iterator<T, -1>;
  13. array()
  14. : ary()
  15. {}
  16. array(const array& oth)
  17. {
  18. auto it_l = begin();
  19. auto it_o = oth.cbegin();
  20. for(size_t i = 0; i < sz; ++i)
  21. {
  22. new(&*(it_l++)) T(*(it_o++));
  23. }
  24. }
  25. template<typename ...U>
  26. array(U&& ...values)
  27. : ary{gp::move((T&&)values)...}
  28. {}
  29. array(array&& values)
  30. {
  31. gp::move_uninitialized<T>(
  32. values,
  33. *this
  34. );
  35. }
  36. template<>
  37. array<T[sz]>(T (& oth)[sz]) {
  38. gp::move_uninitialized<T>(
  39. gp::nameless_range(oth, oth+sz),
  40. gp::nameless_range(begin(), end())
  41. );
  42. }
  43. template<>
  44. array<T[sz]>(T (&& oth)[sz]) {
  45. gp::move_uninitialized(
  46. gp::nameless_range(oth, oth+sz),
  47. gp::nameless_range(begin(), end())
  48. );
  49. }
  50. array& operator=(array& oth)
  51. {
  52. for(size_t i = 0; i < sz; ++i)
  53. {
  54. ary[i]=oth[i];
  55. }
  56. return *this;
  57. }
  58. array& operator=(array&& oth)
  59. {
  60. for(size_t i = 0; i < sz; ++i)
  61. {
  62. ary[i]=gp::move(oth[i]);
  63. }
  64. return *this;
  65. }
  66. constexpr T& operator[] (size_t off)
  67. {
  68. if constexpr (gp_config::has_buffer_bounds)
  69. {
  70. gp_config::assertion(
  71. off < sz,
  72. "Array bounds infringed"
  73. );
  74. }
  75. return ary[off];
  76. }
  77. constexpr const T& operator[] (size_t off) const
  78. {
  79. return ary[off];
  80. }
  81. constexpr size_t size() const
  82. {
  83. return sz;
  84. }
  85. constexpr pointer_iterator<T, 1> begin()
  86. {
  87. return associated_iterator(&ary[0]);
  88. }
  89. constexpr pointer_iterator<T, 1> end()
  90. {
  91. return associated_iterator(&ary[sz]);
  92. }
  93. constexpr const_pointer_iterator<T, 1> cbegin() const
  94. {
  95. return associated_const_iterator(&ary[0]);
  96. }
  97. constexpr const_pointer_iterator<T, 1> cend() const
  98. {
  99. return associated_const_iterator(&ary[sz]);
  100. }
  101. constexpr pointer_iterator<T, -1> rbegin()
  102. {
  103. return associated_riterator(&ary[sz-1]);
  104. }
  105. constexpr pointer_iterator<T, -1> rend()
  106. {
  107. return associated_riterator(ary-1);
  108. }
  109. constexpr const_pointer_iterator<T, -1> crbegin() const
  110. {
  111. return associated_const_riterator(&ary[sz-1]);
  112. }
  113. constexpr const_pointer_iterator<T, -1> crend() const
  114. {
  115. return associated_const_riterator(ary-1);
  116. }
  117. constexpr bool operator==(const array& oth) const
  118. {
  119. for(size_t idx = 0; idx<sz; idx++)
  120. {
  121. if(ary[idx] != oth.ary[idx])
  122. {
  123. return false;
  124. }
  125. }
  126. return true;
  127. }
  128. constexpr bool operator!=(const array& oth) const
  129. {
  130. return !(*this == oth);
  131. }
  132. gp::buffer<T> as_buffer()
  133. {
  134. return gp::buffer<T>{(T*)ary, (T*)ary+sz};
  135. }
  136. };
  137. }