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.

167 lines
2.9 KiB

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