add a simple helper class that allows to store data members conditionally
the class takes a boolean parameter as its first template parameter and a type name as the second. if the boolean parameter is false, nothing is stored, else an object of the type of the second template parameter gets created. this mechanism allows to disable member attributes based on compile time conditions. The usage semantics of that class are that of a smart pointer class, i.e., the equivalent of ``` Foo foo; foo.bar() ``` is ``` Opm::ConditionalStorage<true, Foo> foo; foo->bar(); ``` If the condition argument for the ConditionalStorage is false, that code will still compile but an exception is thrown at runtime.
This commit is contained in:
parent
a346cf5e16
commit
0b097b60f4
@ -57,6 +57,7 @@ list (APPEND PROGRAM_SOURCE_FILES
|
||||
|
||||
|
||||
list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/ConditionalStorage.hpp
|
||||
opm/common/ErrorMacros.hpp
|
||||
opm/common/Exceptions.hpp
|
||||
opm/common/ResetLocale.hpp
|
||||
|
167
opm/common/ConditionalStorage.hpp
Normal file
167
opm/common/ConditionalStorage.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
// -*- 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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::ConditionalStorage
|
||||
*/
|
||||
#ifndef OPM_CONDITIONAL_STORAGE_HH
|
||||
#define OPM_CONDITIONAL_STORAGE_HH
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/Exceptions.hpp>
|
||||
#include <opm/common/Unused.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace Opm {
|
||||
/*!
|
||||
* \ingroup Common
|
||||
*
|
||||
* \brief A simple class which only stores a given member attribute if a boolean
|
||||
* condition is true
|
||||
*
|
||||
* If the condition is false, nothing is stored and an exception is thrown when trying to
|
||||
* access the object.
|
||||
*/
|
||||
template <bool cond, class T>
|
||||
class ConditionalStorage
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
static constexpr bool condition = cond;
|
||||
|
||||
ConditionalStorage()
|
||||
{}
|
||||
|
||||
ConditionalStorage(const T& v)
|
||||
: data_(v)
|
||||
{}
|
||||
|
||||
ConditionalStorage(T&& v)
|
||||
: data_(std::move(v))
|
||||
{}
|
||||
|
||||
template <class ...Args>
|
||||
ConditionalStorage(Args... args)
|
||||
: data_(args...)
|
||||
{}
|
||||
|
||||
ConditionalStorage(const ConditionalStorage& t)
|
||||
: data_(t.data_)
|
||||
{};
|
||||
|
||||
ConditionalStorage(ConditionalStorage&& t)
|
||||
: data_(std::move(t.data_))
|
||||
{};
|
||||
|
||||
ConditionalStorage& operator=(const ConditionalStorage& v)
|
||||
{
|
||||
data_ = v.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConditionalStorage& operator=(ConditionalStorage&& v)
|
||||
{
|
||||
data_ = std::move(v.data_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& operator*() const
|
||||
{ return data_; }
|
||||
T& operator*()
|
||||
{ return data_; }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &data_; }
|
||||
T* operator->()
|
||||
{ return &data_; }
|
||||
|
||||
private:
|
||||
T data_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ConditionalStorage<false, T>
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
static constexpr bool condition = false;
|
||||
|
||||
ConditionalStorage()
|
||||
{
|
||||
// ensure that T has a default constructor without actually calling it
|
||||
if (false) {
|
||||
T OPM_UNUSED dummy; // <- if the compiler bails out here, T does not have a default constructor
|
||||
}
|
||||
}
|
||||
|
||||
ConditionalStorage(const T& v)
|
||||
{
|
||||
// ensure that T has a default constructor without actually calling it
|
||||
if (false) {
|
||||
T OPM_UNUSED dummy(v); // <- if the compiler bails out here, T does not have a copy constructor
|
||||
}
|
||||
}
|
||||
|
||||
ConditionalStorage(const ConditionalStorage &)
|
||||
{
|
||||
// copying an empty conditional storage object does not do anything.
|
||||
};
|
||||
|
||||
template <class ...Args>
|
||||
ConditionalStorage(Args... args)
|
||||
{
|
||||
// ensure that the arguments are valid without actually calling the constructor
|
||||
// of T
|
||||
if (false) {
|
||||
T OPM_UNUSED dummy(args...); // <- if the compiler bails out here, T does not have the requested constructor
|
||||
}
|
||||
}
|
||||
|
||||
ConditionalStorage& operator=(const ConditionalStorage& v)
|
||||
{
|
||||
// ensure that the stored object can actually be assined to but not actually do
|
||||
// anything
|
||||
if (false) {
|
||||
T *dummy;
|
||||
(*dummy) = (*dummy); // <- if the compiler bails out here, T does not have an assignment operator
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& operator*() const
|
||||
{ OPM_THROW(std::logic_error, "data member deactivated"); }
|
||||
T& operator*()
|
||||
{ OPM_THROW(std::logic_error, "data member deactivated"); }
|
||||
|
||||
const T* operator->() const
|
||||
{ OPM_THROW(std::logic_error, "data member deactivated"); }
|
||||
T* operator->()
|
||||
{ OPM_THROW(std::logic_error, "data member deactivated"); }
|
||||
};
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user