From 1e7d566a930d2b3ee15b39b48d708cef57c970c1 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 20 Mar 2019 12:36:36 +0100 Subject: [PATCH] clean up the new FastSmallVector class also, this fixes some potential memory leaks if vectors of different sizes are assigned and it fixes the assignment-to-self (`x = x`) case. --- bin/genEvalSpecializations.py | 2 +- opm/material/common/FastSmallVector.hpp | 146 ++++++++++++++++++ opm/material/densead/DynamicEvaluation.hpp | 2 +- opm/material/densead/FastSmallVector.hpp | 164 --------------------- 4 files changed, 148 insertions(+), 166 deletions(-) create mode 100644 opm/material/common/FastSmallVector.hpp delete mode 100644 opm/material/densead/FastSmallVector.hpp diff --git a/bin/genEvalSpecializations.py b/bin/genEvalSpecializations.py index 87f71ea33..0aee8ef80 100755 --- a/bin/genEvalSpecializations.py +++ b/bin/genEvalSpecializations.py @@ -79,7 +79,7 @@ specializationTemplate = \ #include {% if numDerivs < 0 %}\ -#include "FastSmallVector.hpp" +#include {% else %}\ #include {% endif %}\ diff --git a/opm/material/common/FastSmallVector.hpp b/opm/material/common/FastSmallVector.hpp new file mode 100644 index 000000000..04815036e --- /dev/null +++ b/opm/material/common/FastSmallVector.hpp @@ -0,0 +1,146 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ +/*! + * \file + * + * \copydoc Opm::FastSmallVector + */ +#ifndef OPM_FAST_SMALL_VECTOR_HPP +#define OPM_FAST_SMALL_VECTOR_HPP + +#include +#include + +namespace Opm { + +template +class FastSmallVector +{ +public: + FastSmallVector() + { + size_ = 0; + dataPtr_ = smallBuf_.data(); + } + + explicit FastSmallVector(const size_t numElem) + { + init_(numElem); + } + + FastSmallVector(const size_t numElem, const ValueType value) + { + init_(numElem); + + std::fill(dataPtr_, dataPtr_ + size_, value); + } + + FastSmallVector(const FastSmallVector& other) + { + size_ = 0; + dataPtr_ = smallBuf_.data(); + + (*this) = other; + } + + FastSmallVector(FastSmallVector&& other) + { + size_ = 0; + dataPtr_ = smallBuf_.data(); + + (*this) = std::move(other); + } + + ~FastSmallVector() + { + if (dataPtr_ != smallBuf_.data()) + delete [] dataPtr_; + } + + + FastSmallVector& operator=(FastSmallVector&& other) + { + if (dataPtr_ != smallBuf_.data() && dataPtr_ != other.dataPtr_) + delete [] dataPtr_; + + size_ = other.size_; + if (size_ <= N) { + smallBuf_ = std::move(other.smallBuf_); + dataPtr_ = smallBuf_.data(); + } + else + dataPtr_ = other.dataPtr_; + + other.dataPtr_ = nullptr; + other.size_ = 0; + + return (*this); + } + + FastSmallVector& operator=(const FastSmallVector& other) + { + size_ = other.size_; + + if (size_ <= N) { + smallBuf_ = other.smallBuf_; + dataPtr_ = smallBuf_.data(); + } + else if (dataPtr_ != other.dataPtr_) { + if (dataPtr_ != smallBuf_.data()) + delete[] dataPtr_; + dataPtr_ = new ValueType[size_]; + + std::copy(other.dataPtr_, other.dataPtr_ + size_, dataPtr_); + } + + return (*this); + } + + ValueType& operator[](size_t idx) + { return dataPtr_[idx]; } + + const ValueType& operator[](size_t idx) const + { return dataPtr_[idx]; } + + size_t size() const + { return size_; } + +private: + void init_(size_t numElem) + { + size_ = numElem; + + if (size_ > N) + dataPtr_ = new ValueType[size_]; + else + dataPtr_ = smallBuf_.data(); + } + + std::array smallBuf_; + std::size_t size_; + ValueType* dataPtr_; +}; + +} // namespace Opm + +#endif // OPM_FAST_SMALL_VECTOR_HPP diff --git a/opm/material/densead/DynamicEvaluation.hpp b/opm/material/densead/DynamicEvaluation.hpp index ce8effdef..09488143e 100644 --- a/opm/material/densead/DynamicEvaluation.hpp +++ b/opm/material/densead/DynamicEvaluation.hpp @@ -37,7 +37,7 @@ #include -#include "FastSmallVector.hpp" +#include #include #include #include diff --git a/opm/material/densead/FastSmallVector.hpp b/opm/material/densead/FastSmallVector.hpp deleted file mode 100644 index f4ad8eb90..000000000 --- a/opm/material/densead/FastSmallVector.hpp +++ /dev/null @@ -1,164 +0,0 @@ -#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_; -} - -} -}