smart_pointer.h
Go to the documentation of this file.
#ifndef _RHEO_SMART_POINTER_H
#define _RHEO_SMART_POINTER_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// Rheolef 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.
//
// Rheolef 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 Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =========================================================================
// author: Pierre.Saramito@imag.fr
// date: 27 january 2000, updated 11 may 2012.
namespace rheolef {
} // namespace rheolef
#include "rheolef/compiler.h"
// -----------------------------------------------------------------------
// smart_pointer_base<T,Copy>
// -----------------------------------------------------------------------
namespace rheolef {
template <class T, class C>
class smart_pointer_base {
public:
struct internal {};
// allocators:
smart_pointer_base (T* p = 0);
smart_pointer_base (const smart_pointer_base<T,C>&);
smart_pointer_base (void* count, internal);
smart_pointer_base<T,C>& operator= (const smart_pointer_base<T,C>&);
~smart_pointer_base ();
// accessors:
const T* pointer () const;
const T& data () const;
const T* operator-> () const;
const T& operator* () const;
// modifiers:
T* pointer ();
T& data ();
T* operator-> ();
T& operator* ();
// implementation:
private:
struct counter {
T* _p;
int _n;
counter (T* p = 0);
~counter ();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
int operator++ ();
int operator-- ();
#pragma GCC diagnostic pop
private:
counter (const counter&);
counter& operator= (const counter&);
};
counter *_count;
public:
#ifndef TO_CLEAN
int reference_counter() const { return _count != 0 ? _count->_n : -1; }
#endif // TO_CLEAN
counter* get_count() const { return _count; }
};
// -----------------------------------------------------------------------
// counter: inlined
// -----------------------------------------------------------------------
template <class T, class C>
inline
smart_pointer_base<T,C>::counter::counter (T* p)
: _p(p), _n(1)
{
}
template <class T, class C>
inline
smart_pointer_base<T,C>::counter::~counter ()
{
delete_macro(_p);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
template <class T, class C>
inline
int
smart_pointer_base<T,C>::counter::operator++ ()
{
return ++_n;
}
template <class T, class C>
inline
int
smart_pointer_base<T,C>::counter::operator-- ()
{
if (--_n != 0) return _n;
delete(this);
return 0;
}
#pragma GCC diagnostic pop
// -----------------------------------------------------------------------
// smart_pointer_base: inlined
// -----------------------------------------------------------------------
template <class T, class C>
inline
smart_pointer_base<T,C>::smart_pointer_base (T* p)
: _count(new_macro(counter(p)))
{
}
template <class T, class C>
inline
smart_pointer_base<T,C>::smart_pointer_base (void* count, internal)
: _count(static_cast<counter*>(count))
{
++(*_count);
}
template <class T, class C>
inline
smart_pointer_base<T,C>::smart_pointer_base (const smart_pointer_base& sp)
: _count(sp._count)
{
++(*_count);
}
template <class T, class C>
inline
smart_pointer_base<T,C>::~smart_pointer_base ()
{
if (_count != 0) { --(*_count); }
}
template <class T, class C>
inline
smart_pointer_base<T,C>&
smart_pointer_base<T,C>::operator= (const smart_pointer_base& sp)
{
if (_count != sp._count) {
--(*_count);
_count = sp._count;
++(*_count);
}
return *this;
}
template <class T, class C>
inline
const T*
smart_pointer_base<T,C>::pointer () const
{
return _count -> _p;
}
template <class T, class C>
inline
const T&
smart_pointer_base<T,C>::data () const
{
return *pointer();
}
template <class T, class C>
inline
const T*
smart_pointer_base<T,C>::operator-> () const
{
return pointer();
}
template <class T, class C>
inline
const T&
smart_pointer_base<T,C>::operator* () const
{
return data();
}
template <class T, class C>
inline
T*
smart_pointer_base<T,C>::pointer ()
{
// here is tthe true copy semantic:
if (_count -> _p == 0) return 0;
if (_count -> _n > 1) {
--(_count-> _n);
T* q = C()(*(_count -> _p));
_count = new_macro (counter(q));
}
return _count -> _p;
}
template <class T, class C>
inline
T*
smart_pointer_base<T,C>::operator-> ()
{
return pointer();
}
template <class T, class C>
inline
T&
smart_pointer_base<T,C>::data ()
{
return *pointer();
}
template <class T, class C>
inline
T&
smart_pointer_base<T,C>::operator* ()
{
return data();
}
// -----------------------------------------------------------------------
// copy functors implementing the three possible copy semantics
// -----------------------------------------------------------------------
namespace details {
// constructor_copy uses the copy constructor of the object - used for simple types
template <typename T>
struct constructor_copy {
T* operator() (const T& data) throw() { return new_macro(T(data)); }
};
// clone_copy uses the clone method of the object - used for polymorphic types
template <typename T>
struct clone_copy {
T* operator() (const T& from) throw() { return from.clone(); }
};
// no_copy throws an exception - used for types that cannot be copied
template <typename T>
struct no_copy {
T* operator() (const T& from) {
error_macro ("no_copy functor called (illegal copy)");
return 0;
}
};
} // end namespace stlplus
// -----------------------------------------------------------------------
// smart_pointer<T>
// -----------------------------------------------------------------------
// [verbatim_smart_pointer]
template <typename T>
class smart_pointer : public smart_pointer_base<T, details::constructor_copy<T> > {
typedef details::constructor_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer (T* p = 0) : base (p) {}
smart_pointer (void* count, internal i) : base(count,i) {}
smart_pointer (const smart_pointer<T>& x) : base(x) {}
smart_pointer<T>& operator= (const smart_pointer<T>& x) {
base::operator= (x); return *this; }
~smart_pointer() {}
};
// [verbatim_smart_pointer]
// -----------------------------------------------------------------------
// smart_pointer_clone<T>
// -----------------------------------------------------------------------
// [verbatim_smart_pointer_clone]
template <typename T>
class smart_pointer_clone : public smart_pointer_base<T, details::clone_copy<T> > {
typedef details::clone_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer_clone (T* p = 0) : base (p) {}
smart_pointer_clone (void* count, internal i) : base(count,i) {}
smart_pointer_clone (const smart_pointer_clone<T>& x) : base(x) {}
smart_pointer_clone<T>& operator= (const smart_pointer_clone<T>& x) {
base::operator= (x); return *this; }
~smart_pointer_clone() {}
};
// [verbatim_smart_pointer_clone]
// -----------------------------------------------------------------------
// smart_pointer_nocopy<T>
// -----------------------------------------------------------------------
// [verbatim_smart_pointer_nocopy]
template <typename T>
class smart_pointer_nocopy : public smart_pointer_base<T, details::no_copy<T> > {
typedef details::no_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer_nocopy (T* p = 0) : base (p) {}
smart_pointer_nocopy (void* count, internal i) : base(count,i) {}
smart_pointer_nocopy (const smart_pointer_nocopy<T>& x) : base(x) {}
smart_pointer_nocopy<T>& operator= (const smart_pointer_nocopy<T>& x) {
base::operator= (x); return *this; }
~smart_pointer_nocopy() {}
};
// [verbatim_smart_pointer_nocopy]
}// namespace rheolef
#endif // _RHEO_SMART_POINTER_H
#ifdef _RHEO_SMART_POINTER_TST_CC
// -----------------------------------------------------------------------
// smart_pointer_tst.cc : here for doxygen, to avoid INPUT in util/tst
// -----------------------------------------------------------------------
using namespace rheolef;
using namespace std;
// [verbatim_smart_pointer_tst]
// data representation (could be file "container_data.h")
typedef int T;
class container_data {
private:
T *values;
int n;
public:
container_data (const container_data& x)
: values(new T[x.n]), n(x.n)
{ for (int i=0; i<n;i++) values[i]=x.values[i];}
container_data& operator= (const container_data& x) {
n = x.n;
values = new T[n];
for (int i=0; i<n;i++) values[i]=x.values[i];
return *this;
}
// a customized constructor
explicit container_data(int n1)
: values(new T[n1]), n(n1) {}
~container_data() { delete [] values; }
// read and write accessors are separated
const T& operator[](int i) const
{ return values[i]; }
T& operator[](int i)
{ return values[i]; }
};
// an interface to data via the Objet class
// that count occurrence (could be "container.h")
//
class container : private smart_pointer<container_data> {
public:
// the customized cstor
explicit container(int n = 0);
// read/write accessors
const T& operator[](int i) const;
T& operator[](int i);
};
// here is the implementation of the interface
// (could be "container.c")
//
container::container (int n)
: smart_pointer<container_data> (new container_data(n))
{}
const T&
container::operator[] (int i) const {
// use read access data()
return data().operator[] (i);
}
T&
container::operator[] (int i) {
// use write access data() that check occurrence count
return data().operator [] (i);
}
// test program
int main() {
container A(10);
A[1] = 1;
container B = A;
B[1] = 2;
if (A[1] == B[1]) {
std::cerr << "fatal: It is not a true copy semantic." << std::endl;
exit(1);
}
std::cerr << "It seems to be a true copy semantic." << std::endl;
}
// [verbatim_smart_pointer_tst]
#endif // _RHEO_SMART_POINTER_TST_CC
main
int main(int argc, char **argv)
Definition: csr.cc:270
rheolef::smart_pointer_base
Definition: smart_pointer.h:131
rheolef::smart_pointer_base::data
T & data()
Definition: smart_pointer.h:308
rheolef::smart_pointer_base::data
const T & data() const
Definition: smart_pointer.h:266
rheolef::smart_pointer_base::smart_pointer_base
smart_pointer_base(T *p=0)
Definition: smart_pointer.h:220
rheolef::smart_pointer_base::smart_pointer_base
smart_pointer_base(void *count, internal)
Definition: smart_pointer.h:226
rheolef::smart_pointer_base::operator*
const T & operator*() const
Definition: smart_pointer.h:280
rheolef::smart_pointer_base::pointer
const T * pointer() const
Definition: smart_pointer.h:259
rheolef::smart_pointer_base::smart_pointer_base
smart_pointer_base(const smart_pointer_base< T, C > &)
rheolef::smart_pointer_base::reference_counter
int reference_counter() const
Definition: smart_pointer.h:177
rheolef::smart_pointer_base::pointer
T * pointer()
Definition: smart_pointer.h:287
rheolef::smart_pointer_base::~smart_pointer_base
~smart_pointer_base()
Definition: smart_pointer.h:240
rheolef::smart_pointer_base::operator->
const T * operator->() const
Definition: smart_pointer.h:273
rheolef::smart_pointer_base::operator=
smart_pointer_base< T, C > & operator=(const smart_pointer_base< T, C > &)
Definition: smart_pointer.h:247
rheolef::smart_pointer_base::get_count
counter * get_count() const
Definition: smart_pointer.h:179
rheolef::smart_pointer_clone
Definition: smart_pointer.h:370
rheolef::smart_pointer_clone::operator=
smart_pointer_clone< T > & operator=(const smart_pointer_clone< T > &x)
Definition: smart_pointer.h:379
rheolef::smart_pointer_clone::smart_pointer_clone
smart_pointer_clone(T *p=0)
Definition: smart_pointer.h:376
rheolef::smart_pointer_clone::smart_pointer_clone
smart_pointer_clone(const smart_pointer_clone< T > &x)
Definition: smart_pointer.h:378
rheolef::smart_pointer_clone::handled_type
T handled_type
Definition: smart_pointer.h:374
rheolef::smart_pointer_clone::~smart_pointer_clone
~smart_pointer_clone()
Definition: smart_pointer.h:381
rheolef::smart_pointer_clone::smart_pointer_clone
smart_pointer_clone(void *count, internal i)
Definition: smart_pointer.h:377
rheolef::smart_pointer_nocopy
Definition: smart_pointer.h:389
rheolef::smart_pointer_nocopy::smart_pointer_nocopy
smart_pointer_nocopy(const smart_pointer_nocopy< T > &x)
Definition: smart_pointer.h:397
rheolef::smart_pointer_nocopy::~smart_pointer_nocopy
~smart_pointer_nocopy()
Definition: smart_pointer.h:400
rheolef::smart_pointer_nocopy::smart_pointer_nocopy
smart_pointer_nocopy(T *p=0)
Definition: smart_pointer.h:395
rheolef::smart_pointer_nocopy::handled_type
T handled_type
Definition: smart_pointer.h:393
rheolef::smart_pointer_nocopy::operator=
smart_pointer_nocopy< T > & operator=(const smart_pointer_nocopy< T > &x)
Definition: smart_pointer.h:398
rheolef::smart_pointer_nocopy::smart_pointer_nocopy
smart_pointer_nocopy(void *count, internal i)
Definition: smart_pointer.h:396
rheolef::smart_pointer
see the smart_pointer page for the full documentation
Definition: smart_pointer.h:351
rheolef::smart_pointer::smart_pointer
smart_pointer(void *count, internal i)
Definition: smart_pointer.h:358
rheolef::smart_pointer::handled_type
T handled_type
Definition: smart_pointer.h:355
rheolef::smart_pointer::smart_pointer
smart_pointer(const smart_pointer< T > &x)
Definition: smart_pointer.h:359
rheolef::smart_pointer::operator=
smart_pointer< T > & operator=(const smart_pointer< T > &x)
Definition: smart_pointer.h:360
rheolef::smart_pointer::~smart_pointer
~smart_pointer()
Definition: smart_pointer.h:362
rheolef::smart_pointer::smart_pointer
smart_pointer(T *p=0)
Definition: smart_pointer.h:357
rheolef::std
Definition: vec_expr_v2.h:402
error_macro
#define error_macro(message)
Definition: dis_macros.h:49
T
Expr1::float_type T
Definition: field_expr.h:261
mkgeo_ball.n
int n
Definition: mkgeo_ball.sh:150
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
p
Definition: sphere.icc:25
rheolef::details::clone_copy
Definition: smart_pointer.h:332
rheolef::details::clone_copy::operator()
T * operator()(const T &from)
Definition: smart_pointer.h:333
rheolef::details::constructor_copy
Definition: smart_pointer.h:326
rheolef::details::constructor_copy::operator()
T * operator()(const T &data)
Definition: smart_pointer.h:327
rheolef::details::no_copy
Definition: smart_pointer.h:338
rheolef::details::no_copy::operator()
T * operator()(const T &from)
Definition: smart_pointer.h:339
rheolef::smart_pointer_base::internal
Definition: smart_pointer.h:134