singular_refobj.hh
Go to the documentation of this file.
/* -*- mia-c++ -*-
*
* This file is part of MIA - a toolbox for medical image analysis
* Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
*
* MIA 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 MIA; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef mia_singular_refobj_hh
#define mia_singular_refobj_hh
#include <mia/core/defines.hh>
#include <cassert>
NS_MIA_BEGIN
template <typename T>
class TSingleReferencedObject
{
public:
struct Destructor {
Destructor() {}
virtual void operator ()(T& MIA_PARAM_UNUSED(data)) const = 0;
};
struct EmptyDestructor : public Destructor {
EmptyDestructor() {}
virtual void operator ()(T& MIA_PARAM_UNUSED(data))const {}
};
static const EmptyDestructor empty_destructor;
TSingleReferencedObject();
TSingleReferencedObject(T data, const Destructor& d = empty_destructor);
TSingleReferencedObject(const TSingleReferencedObject<T>& other);
TSingleReferencedObject& operator = (const TSingleReferencedObject<T>& other);
TSingleReferencedObject(TSingleReferencedObject<T>&& other);
TSingleReferencedObject& operator = (TSingleReferencedObject<T>&& other);
~TSingleReferencedObject();
operator T()const;
unsigned get_refcount()const;
private:
class TheObject
{
public:
TheObject(T data, const TSingleReferencedObject::Destructor& d);
~TheObject();
void add_ref();
bool del_ref();
T get() const;
unsigned get_refcount()const;
private:
TheObject(const TheObject& data) = delete;
TheObject& operator = (const TheObject& data) = delete;
T m_data;
unsigned m_refcount;
const Destructor& m_destructor;
};
TheObject *m_object;
};
template <typename T>
const typename TSingleReferencedObject<T>::EmptyDestructor TSingleReferencedObject<T>::empty_destructor;
template <typename T>
TSingleReferencedObject<T>::TSingleReferencedObject():
m_object(nullptr)
{
}
template <typename T>
TSingleReferencedObject<T>::TSingleReferencedObject(T data, const Destructor& d)
{
m_object = new TheObject(data, d);
}
template <typename T>
TSingleReferencedObject<T>::TSingleReferencedObject(const TSingleReferencedObject<T>& other)
{
m_object = other.m_object;
if (m_object)
m_object->add_ref();
}
template <typename T>
TSingleReferencedObject<T>& TSingleReferencedObject<T>::operator = (const TSingleReferencedObject<T>& other)
{
if (m_object)
m_object->del_ref();
m_object = other.m_object;
if (m_object)
m_object->add_ref();
return *this;
}
template <typename T>
TSingleReferencedObject<T>::TSingleReferencedObject(TSingleReferencedObject<T>&& other):
m_object(other.m_object)
{
other.m_object = nullptr;
}
template <typename T>
TSingleReferencedObject<T>& TSingleReferencedObject<T>::operator = (TSingleReferencedObject<T>&& other)
{
if (&other != this) {
if (m_object)
m_object->del_ref();
m_object = other.m_object;
other.m_object = nullptr;
}
return *this;
}
template <typename T>
TSingleReferencedObject<T>::~TSingleReferencedObject()
{
if (m_object)
if (m_object->del_ref())
delete m_object;
}
template <typename T>
TSingleReferencedObject<T>::operator T() const
{
return m_object->get();
}
template <typename T>
unsigned TSingleReferencedObject<T>::get_refcount()const
{
if (m_object)
return m_object->get_refcount();
else
return 0;
}
template <typename T>
TSingleReferencedObject<T>::TheObject::TheObject(T data, const Destructor& d):
m_data(data),
m_refcount(1),
m_destructor(d)
{
}
template <typename T>
TSingleReferencedObject<T>::TheObject::~TheObject()
{
assert(m_refcount == 0);
m_destructor(m_data);
}
template <typename T>
void TSingleReferencedObject<T>::TheObject::add_ref()
{
++m_refcount;
}
template <typename T>
bool TSingleReferencedObject<T>::TheObject::del_ref()
{
--m_refcount;
return (m_refcount <= 0);
}
template <typename T>
unsigned TSingleReferencedObject<T>::TheObject::get_refcount()const
{
return m_refcount;
}
template <typename T>
T TSingleReferencedObject<T>::TheObject::get() const
{
return m_data;
}
NS_MIA_END
#endif
TSingleReferencedObject::empty_destructor
static const EmptyDestructor empty_destructor
Definition singular_refobj.hh:60
TSingleReferencedObject::get_refcount
unsigned get_refcount() const
Definition singular_refobj.hh:178
TSingleReferencedObject::TSingleReferencedObject
TSingleReferencedObject()
Definition singular_refobj.hh:107
TSingleReferencedObject::~TSingleReferencedObject
~TSingleReferencedObject()
Definition singular_refobj.hh:164
TSingleReferencedObject::operator=
TSingleReferencedObject & operator=(const TSingleReferencedObject< T > &other)
Definition singular_refobj.hh:128
defines.hh
NS_MIA_BEGIN
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition defines.hh:33
NS_MIA_END
#define NS_MIA_END
conveniance define to end the mia namespace
Definition defines.hh:36
TSingleReferencedObject::Destructor
Definition singular_refobj.hh:50
TSingleReferencedObject::Destructor::Destructor
Destructor()
Definition singular_refobj.hh:51
TSingleReferencedObject::Destructor::operator()
virtual void operator()(T &data) const =0
TSingleReferencedObject::EmptyDestructor
Definition singular_refobj.hh:55
TSingleReferencedObject::EmptyDestructor::EmptyDestructor
EmptyDestructor()
Definition singular_refobj.hh:56
TSingleReferencedObject::EmptyDestructor::operator()
virtual void operator()(T &data) const
Definition singular_refobj.hh:57