1. /* snblock.h by K.Tsuru */
  2. /***********************************************************************
  3. SNBlock template class
  4. An array class of variable size is given here. Class objects which has
  5. operator=() are available. The functions memcopy() and memset() are not
  6. used. The array has a size of power of two. For non class object "NCBlock"
  7. class is prepared.
  8. [reference]
  9. R.B.Murray "C++ Strategies and Tactics"
  10. ************************************************************************/
  11. #ifndef SNBLOCK_H
  12. #define SNBLOCK_H
  13. #include <stdio.h>
  14. #include <assert.h>
  15. #include <limits.h>
  16. // A header file of typedef
  17. #ifndef TYPEDEF_H
  18. #include "typedef.h"
  19. #endif // TYPEDEF_H
  20. // Return a minimum integer 2^p which satisfies sz <= 2^p.
  21. uint ceilpow2(uint sz);
  22. template <class T> class SNBlock { // change name Block --> SNBlock
  23. public:
  24. enum ErrorType{ NORMAL = 0, OUT_OF_MEMORY, NULL_COPY };
  25. protected:
  26. ErrorType error; // error information
  27. uint n_elements; // number of elements
  28. T* elements; // pointer of elements
  29. // copy function
  30. void copy_elements(T* dest, const T* src, uint n_copy);
  31. // copy function for operator=()
  32. void copy_block(const SNBlock<T>& a);
  33. // free memory
  34. // Use size(0,0) in non member function.
  35. void mem_free(){
  36. delete[] elements; elements = NULL; n_elements = 0;
  37. }
  38. public:
  39. /**************************************************************************
  40. Change the size of array.
  41. When sz == 0 free the memory.
  42. When copy > 0, copy the old elements to lower region of new array. Upper
  43. elements are undecided.
  44. When copy <= 0, not copy.
  45. Return a really allocated size of power of two.
  46. **************************************************************************/
  47. uint size(uint sz, int copy);
  48. /*************************************************************************
  49. Allocate greater than or equal (n + 1) elements(enlarge only) i.e.
  50. n-th elements is substitutable. When n >= n_elements, double the size.
  51. Copy the old elements to lower region and not initialize the upper region.
  52. If the required memory was allocated return a value one, else zero.
  53. *************************************************************************/
  54. bool reserve(uint n);
  55. // constructor
  56. SNBlock():error(NORMAL), n_elements(0), elements(NULL){}
  57. SNBlock(uint n_elem): error(NORMAL), n_elements(0), elements(NULL){
  58. if(n_elem) size(n_elem, 0); // allocate memory
  59. }
  60. // copy constructor
  61. SNBlock(const SNBlock<T>& a);
  62. virtual ~SNBlock();
  63. uint size() const { return n_elements; }
  64. // Element access, lhs is available
  65. T& operator[](uint index){
  66. #ifndef NDEBUG
  67. assert(index < n_elements);
  68. #endif
  69. return elements[index];
  70. }
  71. // Element access, rhs only
  72. T operator()(uint index) const {
  73. #ifndef NDEBUG
  74. assert(index < n_elements);
  75. #endif
  76. return elements[index];
  77. }
  78. ErrorType Error() {
  79. ErrorType er = error; error = NORMAL; // reset error
  80. return er;
  81. }
  82. // substitution operator
  83. SNBlock<T>& operator=(const SNBlock<T>& a){ copy_block(a); return *this; }
  84. // Element access
  85. T* Elements(){ return elements; }
  86. };
  87. template <class T> void SNBlock<T>::copy_elements(T* dest, const T* src, uint n_copy){
  88. for(uint j = 0; j < n_copy ; j++) dest[j] = src[j];
  89. }
  90. template <class T> bool SNBlock<T>::reserve(uint index){ // ver. 2,17
  91. if(index < n_elements) return true; // has an enough memory
  92. // index > 0
  93. uint new_sz = ceilpow2(index);
  94. if( new_sz == index ) new_sz *= 2u;
  95. size(new_sz, n_elements);
  96. return error == NORMAL;
  97. }
  98. template <class T> uint SNBlock<T>::size(uint sz, int copy){
  99. if(!sz){ mem_free(); return 0; }
  100. // new size
  101. uint new_sz = ceilpow2(sz);
  102. if( new_sz == n_elements ){ // The size is same.
  103. return new_sz;
  104. }
  105. if(copy <= 0) mem_free();// Old elements is not nessesary.
  106. T* new_ele = new T[new_sz];
  107. if(new_ele == NULL){
  108. error = OUT_OF_MEMORY; mem_free(); return 0;
  109. }
  110. // copy
  111. if(copy > 0){
  112. uint n_copy = new_sz < n_elements ? new_sz : n_elements;
  113. copy_elements(new_ele, elements, n_copy);
  114. }
  115. delete[] elements;
  116. elements = new_ele;
  117. n_elements = new_sz;
  118. return n_elements;
  119. }
  120. template <class T> void SNBlock<T>::copy_block(const SNBlock<T>& a){
  121. if( this == &a ) return; // for a = a
  122. error = a.error;
  123. if(n_elements && !a.n_elements) error = NULL_COPY; // Try to copy null.
  124. // no error for n_elements = 0
  125. if( error != NORMAL) return;
  126. // copy
  127. if(size(a.size(), -1) == 0) return; // Try to allocate memory.
  128. #ifndef NDEBUG
  129. assert(a.n_elements == n_elements);
  130. #endif
  131. copy_elements(elements, a.elements, a.n_elements);
  132. }
  133. // copy constructor
  134. template <class T> SNBlock<T>::SNBlock(const SNBlock<T>& a)
  135. :error(a.error), elements( new T[n_elements = a.n_elements] ){
  136. if(elements == NULL){ error = OUT_OF_MEMORY; return; }
  137. copy_elements(elements, a.elements, n_elements);
  138. }
  139. // destructor
  140. template <class T> SNBlock<T>::~SNBlock(){
  141. mem_free();
  142. }
  143. #endif // SNBLOCK_H

snblock.h : last modifiled at 2017/06/05 15:52:36(5,019 bytes)
created at 2016/04/11 11:18:59
The creation time of this html file is 2017/10/11 16:07:52 (Wed Oct 11 16:07:52 2017).