github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/array.hpp (about) 1 #pragma once 2 3 /** 4 @file 5 @brief scoped array and aligned array 6 7 @author MITSUNARI Shigeo(@herumi) 8 */ 9 #include <new> 10 #include <utility> 11 #ifdef _WIN32 12 #include <malloc.h> 13 #else 14 #include <stdlib.h> 15 #endif 16 #include <cybozu/inttype.hpp> 17 18 namespace cybozu { 19 20 inline void *AlignedMalloc(size_t size, size_t alignment) 21 { 22 #ifdef _WIN32 23 return _aligned_malloc(size, alignment); 24 #else 25 void *p; 26 int ret = posix_memalign(&p, alignment, size); 27 return (ret == 0) ? p : 0; 28 #endif 29 } 30 31 inline void AlignedFree(void *p) 32 { 33 #ifdef _WIN32 34 if (p == 0) return; 35 _aligned_free(p); 36 #else 37 free(p); 38 #endif 39 } 40 41 template<class T> 42 class ScopedArray { 43 T *p_; 44 size_t size_; 45 ScopedArray(const ScopedArray&); 46 void operator=(const ScopedArray&); 47 public: 48 explicit ScopedArray(size_t size) 49 : p_(new T[size]) 50 , size_(size) 51 { 52 } 53 ~ScopedArray() 54 { 55 delete[] p_; 56 } 57 T& operator[](size_t idx) CYBOZU_NOEXCEPT { return p_[idx]; } 58 const T& operator[](size_t idx) const CYBOZU_NOEXCEPT { return p_[idx]; } 59 size_t size() const CYBOZU_NOEXCEPT { return size_; } 60 bool empty() const CYBOZU_NOEXCEPT { return size_ == 0; } 61 T* begin() CYBOZU_NOEXCEPT { return p_; } 62 T* end() CYBOZU_NOEXCEPT { return p_ + size_; } 63 const T* begin() const CYBOZU_NOEXCEPT { return p_; } 64 const T* end() const CYBOZU_NOEXCEPT { return p_ + size_; } 65 T* data() CYBOZU_NOEXCEPT { return p_; } 66 const T* data() const CYBOZU_NOEXCEPT { return p_; } 67 }; 68 69 /** 70 T must be POD type 71 16byte aligment array 72 */ 73 template<class T, size_t N = 16, bool defaultDoClear = true> 74 class AlignedArray { 75 T *p_; 76 size_t size_; 77 size_t allocSize_; 78 T *alloc(size_t size) const 79 { 80 T *p = static_cast<T*>(AlignedMalloc(size * sizeof(T), N)); 81 if (p == 0) throw std::bad_alloc(); 82 return p; 83 } 84 void copy(T *dst, const T *src, size_t n) const 85 { 86 for (size_t i = 0; i < n; i++) dst[i] = src[i]; 87 } 88 void setZero(T *p, size_t n) const 89 { 90 for (size_t i = 0; i < n; i++) p[i] = 0; 91 } 92 /* 93 alloc allocN and copy [p, p + copyN) to new p_ 94 don't modify size_ 95 */ 96 void allocCopy(size_t allocN, const T *p, size_t copyN) 97 { 98 T *q = alloc(allocN); 99 copy(q, p, copyN); 100 AlignedFree(p_); 101 p_ = q; 102 allocSize_ = allocN; 103 } 104 public: 105 /* 106 don't clear buffer with zero if doClear is false 107 */ 108 explicit AlignedArray(size_t size = 0, bool doClear = defaultDoClear) 109 : p_(0) 110 , size_(0) 111 , allocSize_(0) 112 { 113 resize(size, doClear); 114 } 115 AlignedArray(const AlignedArray& rhs) 116 : p_(0) 117 , size_(0) 118 , allocSize_(0) 119 { 120 *this = rhs; 121 } 122 AlignedArray& operator=(const AlignedArray& rhs) 123 { 124 if (allocSize_ < rhs.size_) { 125 allocCopy(rhs.size_, rhs.p_, rhs.size_); 126 } else { 127 copy(p_, rhs.p_, rhs.size_); 128 } 129 size_ = rhs.size_; 130 return *this; 131 } 132 #if (CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11) 133 AlignedArray(AlignedArray&& rhs) CYBOZU_NOEXCEPT 134 : p_(rhs.p_) 135 , size_(rhs.size_) 136 , allocSize_(rhs.allocSize_) 137 { 138 rhs.p_ = 0; 139 rhs.size_ = 0; 140 rhs.allocSize_ = 0; 141 } 142 AlignedArray& operator=(AlignedArray&& rhs) CYBOZU_NOEXCEPT 143 { 144 swap(rhs); 145 rhs.clear(); 146 return *this; 147 } 148 #endif 149 /* 150 don't clear buffer with zero if doClear is false 151 @note don't free if shrinked 152 */ 153 void resize(size_t size, bool doClear = defaultDoClear) 154 { 155 // shrink 156 if (size <= size_) { 157 size_ = size; 158 return; 159 } 160 // realloc if necessary 161 if (size > allocSize_) { 162 allocCopy(size, p_, size_); 163 } 164 if (doClear) setZero(p_ + size_, size - size_); 165 size_ = size; 166 } 167 void clear() // not free 168 { 169 size_ = 0; 170 } 171 ~AlignedArray() 172 { 173 AlignedFree(p_); 174 } 175 void swap(AlignedArray& rhs) CYBOZU_NOEXCEPT 176 { 177 std::swap(p_, rhs.p_); 178 std::swap(size_, rhs.size_); 179 std::swap(allocSize_, rhs.allocSize_); 180 } 181 T& operator[](size_t idx) CYBOZU_NOEXCEPT { return p_[idx]; } 182 const T& operator[](size_t idx) const CYBOZU_NOEXCEPT { return p_[idx]; } 183 size_t size() const CYBOZU_NOEXCEPT { return size_; } 184 bool empty() const CYBOZU_NOEXCEPT { return size_ == 0; } 185 T* begin() CYBOZU_NOEXCEPT { return p_; } 186 T* end() CYBOZU_NOEXCEPT { return p_ + size_; } 187 const T* begin() const CYBOZU_NOEXCEPT { return p_; } 188 const T* end() const CYBOZU_NOEXCEPT { return p_ + size_; } 189 T* data() CYBOZU_NOEXCEPT { return p_; } 190 const T* data() const CYBOZU_NOEXCEPT { return p_; } 191 #if (CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11) 192 const T* cbegin() const CYBOZU_NOEXCEPT { return p_; } 193 const T* cend() const CYBOZU_NOEXCEPT { return p_ + size_; } 194 #endif 195 }; 196 197 } // cybozu