1 // Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (Germany).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Nef_2/include/CGAL/Nef_2/geninfo.h $
7 // $Id: geninfo.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
12 
13 #ifndef CGAL_NEF_2_GENINFO_H
14 #define CGAL_NEF_2_GENINFO_H
15 
16 #include <CGAL/license/Nef_2.h>
17 
18 #define CGAL_DEPRECATED_HEADER "<CGAL/Nef_2/geninfo.h>"
19 #define CGAL_DEPRECATED_MESSAGE_DETAILS \
20   "Something like boost::any or boost::variant should be used instead."
21 #include <CGAL/internal/deprecation_warning.h>
22 
23 #include <CGAL/config.h>
24 #include <memory>
25 
26 /*{\Moptions outfile=geninfo.man}*/
27 /*{\Moptions constref=yes}*/
28 /*{\Manpage {geninfo} {T} {Information association via GenPtr} {}}*/
29 
30 template <typename T>
31 struct geninfo {
32   typedef void* GenPtr;
33 
34 /*{\Mdefinition |\Mname| encapsulates information association via
35 generic pointers of type |GenPtr (=void*)|. An object |t| of type |T|
36 is stored directly in a variable |p| of type |GenPtr| if |sizeof(T)|
37 is not larger than |sizeof(GenPtr)| (also called word size). Otherwise
38 |t| is allocated on the heap and referenced via |p|. This class
39 encapsulates the technicalities, however the user always has to obey
40 the order of its usage: |create|-|access/const_access|-|clear|. On
41 misuse memory problems occur.}*/
42 
43 /*{\Moperations 2 1}*/
44 
45   #ifdef CGAL_USE_FORMER_GENINFO
creategeninfo46   static void create(GenPtr& p)
47   /*{\Mstatic create a slot for an object of type |T| referenced
48     via |p|.}*/
49   { if (sizeof(T) <= sizeof(GenPtr)) new((void*)(&p)) T;
50     if (sizeof(T) >  sizeof(GenPtr)) p = (GenPtr) new T;
51   }
52 
accessgeninfo53   static T& access(GenPtr& p)
54   /*{\Mstatic access an object of type |T| via |p|.
55     \precond |p| was initialized via |create| and was not cleared
56     via |clear|.}*/
57   { if (sizeof(T) <= sizeof(GenPtr)) return *(T*)(&p);
58     else                             return *(T*)p;
59   }
60 
const_accessgeninfo61   static const T& const_access(const GenPtr& p)
62   /*{\Mstatic read-only access of an object of type |T| via |p|.
63     \precond |p| was initialized via |create| and was not cleared
64     via |clear|.}*/
65   { if (sizeof(T) <= sizeof(GenPtr)) return *(const T*)(&p);
66     else                             return *(const T*)p;
67   }
68 
cleargeninfo69   static void clear(GenPtr& p)
70   /*{\Mstatic clear the memory used for the object of type |T| via
71      |p|. \precond |p| was initialized via |create|.}*/
72   { if (sizeof(T) <= sizeof(GenPtr)) ((T*)(&p))->~T();
73     if (sizeof(T) >  sizeof(GenPtr)) delete (T*) p;
74     p=0;
75   }
76   #else //CGAL_USE_FORMER_GENINFO
creategeninfo77   static void create(GenPtr& p)  { p = (GenPtr) new T; }
accessgeninfo78   static T& access(GenPtr& p)  { return *(T*)p;  }
const_accessgeninfo79   static const T& const_access(const GenPtr& p)
80   { return *(const T*)p;   }
cleargeninfo81   static void clear(GenPtr& p){
82     delete (T*) p;
83     p=0;
84   }
85   #endif  //CGAL_USE_FORMER_GENINFO
86 
87 };
88 
89 /*{\Mexample In the first example we store a pair of boolean values
90 which normally fit into one word. Thus there will no heap allocation
91 take place.
92 \begin{Mverb}
93   struct A { bool a,b };
94   GenPtr a;
95   geninfo<A>::create(a);
96   A& a_access = geninfo<A>::access(a);
97   geninfo<A>::clear(a);
98 \end{Mverb}
99 The second example uses the heap scheme as two longs do not fit into
100 one word.
101 \begin{Mverb}
102   struct B { long a,b };
103   GenPtr b;
104   geninfo<B>::create(b);
105   B& b_access = geninfo<B>::access(b);
106   geninfo<B>::clear(b);
107 \end{Mverb}
108 Note that usage of the scheme takes away with the actual check for the
109 type size. Even more important this size might depend on the platform
110 which is used to compile the code and thus the scheme enables platform
111 independent programming.}*/
112 
113 #endif //GENINFO_H
114