- /* snblock.h by K.Tsuru */
- /***********************************************************************
- SNBlock template class
- An array class of variable size is given here. Class objects which has
- operator=() are available. The functions memcopy() and memset() are not
- used. The array has a size of power of two. For non class object "NCBlock"
- class is prepared.
-
- [reference]
- R.B.Murray "C++ Strategies and Tactics"
- ************************************************************************/
- #ifndef SNBLOCK_H
- #define SNBLOCK_H
-
- #include <stdio.h>
- #include <assert.h>
- #include <limits.h>
-
- // A header file of typedef
- #ifndef TYPEDEF_H
- #include "typedef.h"
- #endif // TYPEDEF_H
-
- // Return a minimum integer 2^p which satisfies sz <= 2^p.
- uint ceilpow2(uint sz);
-
- template <class T> class SNBlock { // change name Block --> SNBlock
- public:
- enum ErrorType{ NORMAL = 0, OUT_OF_MEMORY, NULL_COPY };
- protected:
- ErrorType error; // error information
- uint n_elements; // number of elements
- T* elements; // pointer of elements
- // copy function
- void copy_elements(T* dest, const T* src, uint n_copy);
- // copy function for operator=()
- void copy_block(const SNBlock<T>& a);
- // free memory
- // Use size(0,0) in non member function.
- void mem_free(){
- delete[] elements; elements = NULL; n_elements = 0;
- }
- public:
- /**************************************************************************
- Change the size of array.
- When sz == 0 free the memory.
- When copy > 0, copy the old elements to lower region of new array. Upper
- elements are undecided.
- When copy <= 0, not copy.
- Return a really allocated size of power of two.
- **************************************************************************/
- uint size(uint sz, int copy);
- /*************************************************************************
- Allocate greater than or equal (n + 1) elements(enlarge only) i.e.
- n-th elements is substitutable. When n >= n_elements, double the size.
- Copy the old elements to lower region and not initialize the upper region.
- If the required memory was allocated return a value one, else zero.
- *************************************************************************/
- bool reserve(uint n);
- // constructor
- SNBlock():error(NORMAL), n_elements(0), elements(NULL){}
- SNBlock(uint n_elem): error(NORMAL), n_elements(0), elements(NULL){
- if(n_elem) size(n_elem, 0); // allocate memory
- }
- // copy constructor
- SNBlock(const SNBlock<T>& a);
-
- virtual ~SNBlock();
- uint size() const { return n_elements; }
-
- // Element access, lhs is available
- T& operator[](uint index){
- #ifndef NDEBUG
- assert(index < n_elements);
- #endif
- return elements[index];
- }
-
- // Element access, rhs only
- T operator()(uint index) const {
- #ifndef NDEBUG
- assert(index < n_elements);
- #endif
- return elements[index];
- }
-
- ErrorType Error() {
- ErrorType er = error; error = NORMAL; // reset error
- return er;
- }
-
- // substitution operator
- SNBlock<T>& operator=(const SNBlock<T>& a){ copy_block(a); return *this; }
- // Element access
- T* Elements(){ return elements; }
- };
-
- template <class T> void SNBlock<T>::copy_elements(T* dest, const T* src, uint n_copy){
- for(uint j = 0; j < n_copy ; j++) dest[j] = src[j];
- }
- template <class T> bool SNBlock<T>::reserve(uint index){ // ver. 2,17
- if(index < n_elements) return true; // has an enough memory
- // index > 0
- uint new_sz = ceilpow2(index);
- if( new_sz == index ) new_sz *= 2u;
- size(new_sz, n_elements);
- return error == NORMAL;
- }
-
- template <class T> uint SNBlock<T>::size(uint sz, int copy){
- if(!sz){ mem_free(); return 0; }
- // new size
- uint new_sz = ceilpow2(sz);
-
- if( new_sz == n_elements ){ // The size is same.
- return new_sz;
- }
-
- if(copy <= 0) mem_free();// Old elements is not nessesary.
- T* new_ele = new T[new_sz];
-
- if(new_ele == NULL){
- error = OUT_OF_MEMORY; mem_free(); return 0;
- }
-
- // copy
- if(copy > 0){
- uint n_copy = new_sz < n_elements ? new_sz : n_elements;
- copy_elements(new_ele, elements, n_copy);
- }
-
- delete[] elements;
- elements = new_ele;
- n_elements = new_sz;
- return n_elements;
- }
-
- template <class T> void SNBlock<T>::copy_block(const SNBlock<T>& a){
- if( this == &a ) return; // for a = a
- error = a.error;
- if(n_elements && !a.n_elements) error = NULL_COPY; // Try to copy null.
- // no error for n_elements = 0
- if( error != NORMAL) return;
-
- // copy
- if(size(a.size(), -1) == 0) return; // Try to allocate memory.
- #ifndef NDEBUG
- assert(a.n_elements == n_elements);
- #endif
- copy_elements(elements, a.elements, a.n_elements);
- }
- // copy constructor
- template <class T> SNBlock<T>::SNBlock(const SNBlock<T>& a)
- :error(a.error), elements( new T[n_elements = a.n_elements] ){
-
- if(elements == NULL){ error = OUT_OF_MEMORY; return; }
-
- copy_elements(elements, a.elements, n_elements);
- }
- // destructor
- template <class T> SNBlock<T>::~SNBlock(){
- mem_free();
- }
- #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).