General Purpose library for Freestanding C++ and POSIX systems
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

176 行
3.1 KiB

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