Array.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. 
  2. // zlib open source license
  3. //
  4. // Copyright (c) 2018 to 2019 David Forsgren Piuva
  5. //
  6. // This software is provided 'as-is', without any express or implied
  7. // warranty. In no event will the authors be held liable for any damages
  8. // arising from the use of this software.
  9. //
  10. // Permission is granted to anyone to use this software for any purpose,
  11. // including commercial applications, and to alter it and redistribute it
  12. // freely, subject to the following restrictions:
  13. //
  14. // 1. The origin of this software must not be misrepresented; you must not
  15. // claim that you wrote the original software. If you use this software
  16. // in a product, an acknowledgment in the product documentation would be
  17. // appreciated but is not required.
  18. //
  19. // 2. Altered source versions must be plainly marked as such, and must not be
  20. // misrepresented as being the original software.
  21. //
  22. // 3. This notice may not be removed or altered from any source
  23. // distribution.
  24. #ifndef DFPSR_COLLECTION_ARRAY
  25. #define DFPSR_COLLECTION_ARRAY
  26. #include <stdint.h>
  27. namespace dsr {
  28. // Inlined Boundchecks.h
  29. void nonZeroLengthCheck(int64_t length, const char* property);
  30. void baseZeroBoundCheck(int64_t index, int64_t length, const char* property);
  31. // The simplest possible automatically deallocating array with bound checks.
  32. // Indices use signed indices, which can be used directly from high-level algorithms.
  33. // Because std::vector is a list of members, not a fixed size array of values.
  34. // Using a list instead of an array makes the code both dangerous and unreadable.
  35. // Using unsigned indices will either force dangerous casting from signed, or prevent
  36. // the ability to loop backwards without crashing when the x < 0u criteria cannot be met.
  37. template <typename T>
  38. class Array {
  39. private:
  40. const int32_t elementCount;
  41. T *elements = nullptr;
  42. public:
  43. // Constructor
  44. Array(const int32_t newLength, const T& defaultValue)
  45. : elementCount(newLength) {
  46. nonZeroLengthCheck(newLength, "New array length");
  47. this->elements = new T[newLength];
  48. for (int32_t index = 0; index < newLength; index++) {
  49. this->elements[index] = defaultValue;
  50. }
  51. }
  52. // No implicit copies, only pass by reference
  53. Array(const Array&) = delete;
  54. Array& operator=(const Array&) = delete;
  55. // Destructor
  56. ~Array() { delete[] this->elements; }
  57. // Element access
  58. T& operator[] (const int32_t index) {
  59. baseZeroBoundCheck(index, this->length(), "Array index");
  60. return this->elements[index];
  61. }
  62. const T& operator[] (const int32_t index) const {
  63. baseZeroBoundCheck(index, this->length(), "Array index");
  64. return this->elements[index];
  65. }
  66. int32_t length() const {
  67. return this->elementCount;
  68. }
  69. };
  70. }
  71. #endif