114 lines
3.7 KiB
C++
114 lines
3.7 KiB
C++
// Copyright (c) 1997-2000 Max-Planck-Institute Saarbruecken (Germany).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org).
|
|
//
|
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Nef_2/include/CGAL/Nef_2/geninfo.h $
|
|
// $Id: geninfo.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
|
//
|
|
//
|
|
// Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
|
|
|
|
#ifndef CGAL_NEF_2_GENINFO_H
|
|
#define CGAL_NEF_2_GENINFO_H
|
|
|
|
#include <CGAL/license/Nef_2.h>
|
|
|
|
#define CGAL_DEPRECATED_HEADER "<CGAL/Nef_2/geninfo.h>"
|
|
#define CGAL_DEPRECATED_MESSAGE_DETAILS \
|
|
"Something like boost::any or boost::variant should be used instead."
|
|
#include <CGAL/internal/deprecation_warning.h>
|
|
|
|
#include <CGAL/config.h>
|
|
#include <memory>
|
|
|
|
/*{\Moptions outfile=geninfo.man}*/
|
|
/*{\Moptions constref=yes}*/
|
|
/*{\Manpage {geninfo} {T} {Information association via GenPtr} {}}*/
|
|
|
|
template <typename T>
|
|
struct geninfo {
|
|
typedef void* GenPtr;
|
|
|
|
/*{\Mdefinition |\Mname| encapsulates information association via
|
|
generic pointers of type |GenPtr (=void*)|. An object |t| of type |T|
|
|
is stored directly in a variable |p| of type |GenPtr| if |sizeof(T)|
|
|
is not larger than |sizeof(GenPtr)| (also called word size). Otherwise
|
|
|t| is allocated on the heap and referenced via |p|. This class
|
|
encapsulates the technicalities, however the user always has to obey
|
|
the order of its usage: |create|-|access/const_access|-|clear|. On
|
|
misuse memory problems occur.}*/
|
|
|
|
/*{\Moperations 2 1}*/
|
|
|
|
#ifdef CGAL_USE_FORMER_GENINFO
|
|
static void create(GenPtr& p)
|
|
/*{\Mstatic create a slot for an object of type |T| referenced
|
|
via |p|.}*/
|
|
{ if (sizeof(T) <= sizeof(GenPtr)) new((void*)(&p)) T;
|
|
if (sizeof(T) > sizeof(GenPtr)) p = (GenPtr) new T;
|
|
}
|
|
|
|
static T& access(GenPtr& p)
|
|
/*{\Mstatic access an object of type |T| via |p|.
|
|
\precond |p| was initialized via |create| and was not cleared
|
|
via |clear|.}*/
|
|
{ if (sizeof(T) <= sizeof(GenPtr)) return *(T*)(&p);
|
|
else return *(T*)p;
|
|
}
|
|
|
|
static const T& const_access(const GenPtr& p)
|
|
/*{\Mstatic read-only access of an object of type |T| via |p|.
|
|
\precond |p| was initialized via |create| and was not cleared
|
|
via |clear|.}*/
|
|
{ if (sizeof(T) <= sizeof(GenPtr)) return *(const T*)(&p);
|
|
else return *(const T*)p;
|
|
}
|
|
|
|
static void clear(GenPtr& p)
|
|
/*{\Mstatic clear the memory used for the object of type |T| via
|
|
|p|. \precond |p| was initialized via |create|.}*/
|
|
{ if (sizeof(T) <= sizeof(GenPtr)) ((T*)(&p))->~T();
|
|
if (sizeof(T) > sizeof(GenPtr)) delete (T*) p;
|
|
p=0;
|
|
}
|
|
#else //CGAL_USE_FORMER_GENINFO
|
|
static void create(GenPtr& p) { p = (GenPtr) new T; }
|
|
static T& access(GenPtr& p) { return *(T*)p; }
|
|
static const T& const_access(const GenPtr& p)
|
|
{ return *(const T*)p; }
|
|
static void clear(GenPtr& p){
|
|
delete (T*) p;
|
|
p=0;
|
|
}
|
|
#endif //CGAL_USE_FORMER_GENINFO
|
|
|
|
};
|
|
|
|
/*{\Mexample In the first example we store a pair of boolean values
|
|
which normally fit into one word. Thus there will no heap allocation
|
|
take place.
|
|
\begin{Mverb}
|
|
struct A { bool a,b };
|
|
GenPtr a;
|
|
geninfo<A>::create(a);
|
|
A& a_access = geninfo<A>::access(a);
|
|
geninfo<A>::clear(a);
|
|
\end{Mverb}
|
|
The second example uses the heap scheme as two longs do not fit into
|
|
one word.
|
|
\begin{Mverb}
|
|
struct B { long a,b };
|
|
GenPtr b;
|
|
geninfo<B>::create(b);
|
|
B& b_access = geninfo<B>::access(b);
|
|
geninfo<B>::clear(b);
|
|
\end{Mverb}
|
|
Note that usage of the scheme takes away with the actual check for the
|
|
type size. Even more important this size might depend on the platform
|
|
which is used to compile the code and thus the scheme enables platform
|
|
independent programming.}*/
|
|
|
|
#endif //GENINFO_H
|