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.

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