diff --git a/opm/material/densead/FastSmallVector.hpp b/opm/material/densead/FastSmallVector.hpp new file mode 100644 index 000000000..f4ad8eb90 --- /dev/null +++ b/opm/material/densead/FastSmallVector.hpp @@ -0,0 +1,164 @@ +#include +#include + +namespace Opm { +namespace DenseAd { + +template +class FastSmallVector +{ +public: + + FastSmallVector(); + explicit FastSmallVector(const size_t num_elem); + FastSmallVector(const size_t num_elem, const ValueType value); + FastSmallVector(const FastSmallVector& other); + FastSmallVector(FastSmallVector&& other); + ~FastSmallVector(); + + FastSmallVector& operator=(const FastSmallVector& other); + FastSmallVector& operator=(FastSmallVector&& other); + + ValueType& operator[](size_t index); + const ValueType& operator[](size_t index) const; + size_t size() const; + +private: + std::array small_buffer_; + std::size_t size_; + ValueType* data_ptr_; +}; + +template +FastSmallVector:: +FastSmallVector() + : size_(0) + , data_ptr_(small_buffer_.data()) +{ +} + +template +FastSmallVector:: +FastSmallVector(const size_t num_elem) + : size_(num_elem) + , data_ptr_(small_buffer_.data()) +{ + if (size_ > N) { + data_ptr_ = new ValueType[num_elem]; + } +} + +template +FastSmallVector:: +FastSmallVector(const size_t num_elem, const ValueType value) + : FastSmallVector(num_elem) +{ + std::fill_n(data_ptr_, size_, value); +} + +template +FastSmallVector:: +FastSmallVector(FastSmallVector&& other) + : size_ (other.size_) +{ + small_buffer_ = std::move(other.small_buffer_); + if (size_ <= N) { + data_ptr_ = small_buffer_.data(); + } else { + data_ptr_ = other.data_ptr_; + } + + other.data_ptr_= nullptr; + other.size_ = 0; +} + +template +FastSmallVector:: +FastSmallVector(const FastSmallVector& other) + : small_buffer_(other.small_buffer_) + , size_(other.size_) +{ + if (size_ <= N) { + data_ptr_ = small_buffer_.data(); + } else { + data_ptr_ = new ValueType[size_]; + memcpy(data_ptr_, other.data_ptr_, size_ * sizeof(ValueType)); + } +} + +template +FastSmallVector& +FastSmallVector:: +operator = (const FastSmallVector&other) +{ + small_buffer_ = other.small_buffer_; + size_ = other.size_; + + if (size_ <= N) { + data_ptr_ = small_buffer_.data(); + } else { + data_ptr_ = new ValueType[size_]; + memcpy(data_ptr_, other.data_ptr_, size_ * sizeof(ValueType)); + } + + return (*this); +} + +template +FastSmallVector& +FastSmallVector:: +operator = (FastSmallVector&& other) +{ + if (data_ptr_ != small_buffer_.data() && data_ptr_ != nullptr) { + delete [] data_ptr_; + } + size_ = other.size_; + + small_buffer_ = std::move(other.small_buffer_); + if (size_ <= N) { + data_ptr_ = small_buffer_.data(); + } else { + data_ptr_ = other.data_ptr_; + } + + other.data_ptr_ = nullptr; + other.size_ = 0; + + return (*this); +} + +template +FastSmallVector:: +~FastSmallVector() +{ + if ((data_ptr_ != small_buffer_.data()) && (data_ptr_ != nullptr)) { + delete [] data_ptr_; + } +} + +template +ValueType& +FastSmallVector:: +operator[](size_t index) +{ + return data_ptr_[index]; +} + +template +const ValueType& +FastSmallVector:: +operator[](size_t index) const +{ + return data_ptr_[index]; +} + +template +size_t +FastSmallVector:: +size() const +{ + return size_; +} + +} +}