klayout/src/db/dbShape.h

2593 lines
79 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program 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.
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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_dbShape
#define HDR_dbShape
#include "dbCommon.h"
#include "tlException.h"
#include "tlReuseVector.h"
#include "dbManager.h"
#include "dbPolygon.h"
#include "dbPath.h"
#include "dbEdge.h"
#include "dbText.h"
#include "dbBox.h"
#include "dbBoxConvert.h"
#include "dbUserObject.h"
#include "dbArray.h"
#include "dbObjectWithProperties.h"
#include <set>
namespace db
{
class Shapes;
/**
* @brief A generic edge iterator
*
* This edge iterator is used to provide edge iterators for simple and
* complex polygons as well.
* The implementation is based on a union scheme. It assumes that the
* iterators represented by the generic instance do not require a special
* copy semantics but can be copied by bytewise copy simply.
*/
template <class C>
class generic_polygon_edge_iterator
{
public:
typedef C coord_type;
typedef db::edge<C> edge_type;
typedef db::disp_trans<C> disp_type;
typedef db::polygon<C> polygon_type;
typedef typename polygon_type::polygon_edge_iterator polygon_edge_iterator_type;
typedef db::simple_polygon<C> simple_polygon_type;
typedef typename simple_polygon_type::polygon_edge_iterator simple_polygon_edge_iterator_type;
typedef db::polygon_ref<polygon_type, disp_type> polygon_ref_type;
typedef typename polygon_ref_type::polygon_edge_iterator polygon_ref_edge_iterator_type;
typedef db::polygon_ref<simple_polygon_type, disp_type> simple_polygon_ref_type;
typedef typename simple_polygon_ref_type::polygon_edge_iterator simple_polygon_ref_edge_iterator_type;
typedef edge_type value_type;
typedef void pointer;
typedef value_type reference;
typedef std::bidirectional_iterator_tag iterator_category;
typedef void difference_type;
enum iterator_type
{
None, SimplePolygon, SimplePolygonRef, Polygon, PolygonRef
};
/**
* @brief Default ctor
*/
generic_polygon_edge_iterator ()
{
m_type = None;
}
/**
* @brief This constructor creates an edge iterator at "begin" for polygons
*
* The iterator stores begin and end and provides a "at_end" method to
* test if the sequence is at the end.
*
* @param begin The start of the sequence
*/
generic_polygon_edge_iterator (const polygon_edge_iterator_type &begin)
{
m_type = Polygon;
new ((char *) m_d.iter) polygon_edge_iterator_type (begin);
}
/**
* @brief This constructor creates an edge iterator at "begin" for polygon references
*
* See former ctor.
*/
generic_polygon_edge_iterator (const polygon_ref_edge_iterator_type &begin)
{
m_type = PolygonRef;
new ((char *) m_d.iter) polygon_ref_edge_iterator_type (begin);
}
/**
* @brief This constructor creates an edge iterator at "begin" for simple polygons
*
* See former ctor.
*/
generic_polygon_edge_iterator (const simple_polygon_edge_iterator_type &begin)
{
m_type = SimplePolygon;
new ((char *) m_d.iter) simple_polygon_edge_iterator_type (begin);
}
/**
* @brief This constructor creates an edge iterator at "begin" for simple polygon references
*
* See former ctor.
*/
generic_polygon_edge_iterator (const simple_polygon_ref_edge_iterator_type &begin)
{
m_type = SimplePolygonRef;
new ((char *) m_d.iter) simple_polygon_ref_edge_iterator_type (begin);
}
/**
* @brief at_end predicate
*/
bool at_end () const
{
return generic_const_f<bool, at_end_f> ();
}
/**
* @brief contour attribute
*/
unsigned int contour () const
{
return generic_const_f<unsigned int, contour_f> ();
}
/**
* @brief Increment operator
*/
generic_polygon_edge_iterator &operator++ ()
{
generic_f<bool, inc_f> ();
return *this;
}
/**
* @brief Decrement operator
*/
generic_polygon_edge_iterator &operator-- ()
{
generic_f<bool, dec_f> ();
return *this;
}
/**
* @brief access operator
*/
edge_type operator* () const
{
return generic_const_f<edge_type, deref_f> ();
}
private:
// This union is there to compute the maximum size required to hold all
// kind of iterators
union iter_size {
char sz1 [sizeof (polygon_edge_iterator_type)];
char sz2 [sizeof (polygon_ref_edge_iterator_type)];
char sz3 [sizeof (simple_polygon_edge_iterator_type)];
char sz4 [sizeof (simple_polygon_ref_edge_iterator_type)];
};
// This member must be first to guarantee alignment on 64bit systems:
// The strange construction and the local dummy class helps to guarantee alignment of the "iter" space
union {
class _align_helper { long l; } _ah;
// Hint: without the sizeof(size_t) offset, gcc 4.4.1 produces invalid iterators for the edge iterator.
// For example, these iterators do not correctly stop but produce more edges than are available.
char iter [sizeof (iter_size) + sizeof (size_t)];
} m_d;
iterator_type m_type;
struct contour_f {
template <class Iter>
unsigned int operator() (const Iter &iter) const
{
return iter.contour ();
}
};
struct at_end_f {
template <class Iter>
bool operator() (const Iter &iter) const
{
return iter.at_end ();
}
};
struct inc_f {
template <class Iter>
bool operator() (Iter &iter) const
{
iter.operator++ ();
return false;
}
};
struct dec_f {
template <class Iter>
bool operator() (Iter &iter) const
{
iter.operator-- ();
return false;
}
};
struct deref_f {
template <class Iter>
edge_type operator() (const Iter &iter) const
{
return iter.operator* ();
}
};
struct at_begin_f {
template <class Iter>
bool operator() (const Iter &iter) const
{
return iter.at_begin ();
}
};
template <class Ret, class Func>
Ret generic_const_f () const
{
Func f;
if (m_type == Polygon) {
return f (*((const polygon_edge_iterator_type *) m_d.iter));
} else if (m_type == PolygonRef) {
return f (*((const polygon_ref_edge_iterator_type *) m_d.iter));
} else if (m_type == SimplePolygon) {
return f (*((const simple_polygon_edge_iterator_type *) m_d.iter));
} else {
return f (*((const simple_polygon_ref_edge_iterator_type *) m_d.iter));
}
}
template <class Ret, class Func>
Ret generic_f ()
{
Func f;
if (m_type == Polygon) {
return f (*((polygon_edge_iterator_type *) m_d.iter));
} else if (m_type == PolygonRef) {
return f (*((polygon_ref_edge_iterator_type *) m_d.iter));
} else if (m_type == SimplePolygon) {
return f (*((simple_polygon_edge_iterator_type *) m_d.iter));
} else {
return f (*((simple_polygon_ref_edge_iterator_type *) m_d.iter));
}
}
};
/**
* @brief A generic point iterator
*
* This point iterator is used to provide point iterators for simple and
* complex polygons as well as paths.
* The implementation is based on a union scheme. It assumes that the
* iterators represented by the generic instance do not require a special
* copy semantics but can be copied by bytewise copy simply.
*/
template <class C>
class generic_point_iterator
{
public:
typedef C coord_type;
typedef db::point<C> point_type;
typedef db::polygon<C> polygon_type;
typedef db::disp_trans<C> disp_type;
typedef typename polygon_type::polygon_contour_iterator polygon_point_iterator_type;
typedef db::polygon_ref<polygon_type, disp_type> polygon_ref_type;
typedef typename polygon_ref_type::polygon_contour_iterator polygon_ref_point_iterator_type;
typedef db::path<C> path_type;
typedef typename path_type::iterator path_point_iterator_type;
typedef db::path_ref<path_type, disp_type> path_ref_type;
typedef typename path_ref_type::iterator path_ref_point_iterator_type;
typedef point_type value_type;
typedef void pointer;
typedef value_type reference;
typedef std::bidirectional_iterator_tag iterator_category;
typedef void difference_type;
enum iterator_type
{
Polygon, PolygonRef, Path, PathRef
};
/**
* @brief This constructor creates an point iterator at "begin" for polygons
*
* The iterator stores begin and end and provides a "at_end" method to
* test if the sequence is at the end.
* This method also applies to simple polygon contours.
*
* @param begin The start of the sequence
*/
generic_point_iterator (const polygon_point_iterator_type &begin)
{
m_type = Polygon;
new ((char *) m_d.iter) polygon_point_iterator_type (begin);
}
/**
* @brief This constructor creates an point iterator at "begin" for polygon references
*
* This method also applies to simple polygon references.
* See former ctor.
*/
generic_point_iterator (const polygon_ref_point_iterator_type &begin)
{
m_type = PolygonRef;
new ((char *) m_d.iter) polygon_ref_point_iterator_type (begin);
}
/**
* @brief This constructor creates an point iterator at "begin" for paths
*
* See former ctor.
*/
generic_point_iterator (const path_point_iterator_type &begin)
{
m_type = Path;
new ((char *) m_d.iter) path_point_iterator_type (begin);
}
/**
* @brief This constructor creates an point iterator at "begin" for path references
*
* See former ctor.
*/
generic_point_iterator (const path_ref_point_iterator_type &begin)
{
m_type = PathRef;
new ((char *) m_d.iter) path_ref_point_iterator_type (begin);
}
/**
* @brief at_end predicate
*/
bool at_end () const
{
return generic_const_f<bool, at_end_f> ();
}
/**
* @brief Increment operator
*/
generic_point_iterator &operator++ ()
{
generic_f<bool, inc_f> ();
return *this;
}
/**
* @brief Decrement operator
*/
generic_point_iterator &operator-- ()
{
generic_f<bool, dec_f> ();
return *this;
}
/**
* @brief access operator
*/
point_type operator* () const
{
return generic_const_f<point_type, deref_f> ();
}
/**
* @brief Sorting order
*/
bool operator< (const generic_point_iterator &d) const
{
if (m_type != d.m_type) {
return m_type < d.m_type;
}
if (m_type == Polygon) {
return *((const polygon_point_iterator_type *) m_d.iter) < *((const polygon_point_iterator_type *) d.m_d.iter);
} else if (m_type == PolygonRef) {
return *((const polygon_ref_point_iterator_type *) m_d.iter) < *((const polygon_ref_point_iterator_type *) d.m_d.iter);
} else if (m_type == Path) {
return *((const path_point_iterator_type *) m_d.iter) < *((const path_point_iterator_type *) d.m_d.iter);
} else {
return *((const path_ref_point_iterator_type *) m_d.iter) < *((const path_ref_point_iterator_type *) d.m_d.iter);
}
}
/**
* @brief Equality
*/
bool operator== (const generic_point_iterator &d) const
{
tl_assert (m_type == d.m_type);
if (m_type == Polygon) {
return *((const polygon_point_iterator_type *) m_d.iter) == *((const polygon_point_iterator_type *) d.m_d.iter);
} else if (m_type == PolygonRef) {
return *((const polygon_ref_point_iterator_type *) m_d.iter) == *((const polygon_ref_point_iterator_type *) d.m_d.iter);
} else if (m_type == Path) {
return *((const path_point_iterator_type *) m_d.iter) == *((const path_point_iterator_type *) d.m_d.iter);
} else {
return *((const path_ref_point_iterator_type *) m_d.iter) == *((const path_ref_point_iterator_type *) d.m_d.iter);
}
}
/**
* @brief Inequality
*/
bool operator!= (const generic_point_iterator &d) const
{
return !operator== (d);
}
private:
// This union is there to compute the maximum size required to hold all
// kind of iterators
union iter_size {
char sz1 [sizeof (polygon_point_iterator_type)];
char sz2 [sizeof (polygon_ref_point_iterator_type)];
char sz3 [sizeof (path_point_iterator_type)];
char sz4 [sizeof (path_ref_point_iterator_type)];
};
// This member must be first to guarantee alignment on 64bit systems:
// The strange construction and the local dummy class helps to guarantee alignment of the "iter" space
union {
class _align_helper { long l; } _ah;
// Hint: without the sizeof(size_t) offset, gcc 4.4.1 produces invalid iterators for the edge iterator.
// For safety the offset is added here as well:
char iter [sizeof (iter_size) + sizeof (size_t)];
} m_d;
iterator_type m_type;
struct at_end_f {
template <class Iter>
bool operator() (const Iter &iter) const
{
return iter.at_end ();
}
};
struct inc_f {
template <class Iter>
bool operator() (Iter &iter) const
{
iter.operator++ ();
return false;
}
};
struct dec_f {
template <class Iter>
bool operator() (Iter &iter) const
{
iter.operator-- ();
return false;
}
};
struct deref_f {
template <class Iter>
point_type operator() (const Iter &iter) const
{
return iter.operator* ();
}
};
struct at_begin_f {
template <class Iter>
bool operator() (const Iter &iter) const
{
return iter.at_begin ();
}
};
template <class Ret, class Func>
Ret generic_const_f () const
{
Func f;
if (m_type == Polygon) {
return f (*((const polygon_point_iterator_type *) m_d.iter));
} else if (m_type == PolygonRef) {
return f (*((const polygon_ref_point_iterator_type *) m_d.iter));
} else if (m_type == Path) {
return f (*((const path_point_iterator_type *) m_d.iter));
} else {
return f (*((const path_ref_point_iterator_type *) m_d.iter));
}
}
template <class Ret, class Func>
Ret generic_f ()
{
Func f;
if (m_type == Polygon) {
return f (*((polygon_point_iterator_type *) m_d.iter));
} else if (m_type == PolygonRef) {
return f (*((polygon_ref_point_iterator_type *) m_d.iter));
} else if (m_type == Path) {
return f (*((path_point_iterator_type *) m_d.iter));
} else {
return f (*((path_ref_point_iterator_type *) m_d.iter));
}
}
};
/**
* @brief A shape proxy
*
* The shape proxy is basically a pointer to a shape of different kinds
* No copy of the shape is created: if the shape proxy is copied the copy still
* points to the original shape. If the original shape is modified or deleted,
* the shape proxy will also point to a modified or invalid shape.
* The proxy can be "null" which means a invalid reference.
*/
class DB_PUBLIC Shape
{
public:
typedef db::Coord coord_type;
typedef coord_traits<coord_type>::area_type area_type;
typedef coord_traits<coord_type>::distance_type distance_type;
typedef coord_traits<coord_type>::perimeter_type perimeter_type;
typedef db::simple_trans<coord_type> trans_type;
typedef db::disp_trans<coord_type> disp_type;
typedef db::unit_trans<coord_type> unit_trans_type;
typedef db::polygon<coord_type> polygon_type;
typedef db::simple_polygon<coord_type> simple_polygon_type;
typedef db::polygon_ref<polygon_type, disp_type> polygon_ref_type;
typedef db::polygon_ref<polygon_type, unit_trans_type> polygon_ptr_type;
typedef db::array<polygon_ptr_type, disp_type> polygon_ptr_array_type;
typedef db::polygon_ref<simple_polygon_type, disp_type> simple_polygon_ref_type;
typedef db::polygon_ref<simple_polygon_type, unit_trans_type> simple_polygon_ptr_type;
typedef db::array<simple_polygon_ptr_type, disp_type> simple_polygon_ptr_array_type;
typedef db::path<coord_type> path_type;
typedef db::path_ref<path_type, disp_type> path_ref_type;
typedef db::path_ref<path_type, unit_trans_type> path_ptr_type;
typedef db::array<path_ptr_type, disp_type> path_ptr_array_type;
typedef db::edge<coord_type> edge_type;
typedef db::text<coord_type> text_type;
typedef db::text_ref<text_type, disp_type> text_ref_type;
typedef db::text_ref<text_type, unit_trans_type> text_ptr_type;
typedef db::array<text_ptr_type, disp_type> text_ptr_array_type;
typedef db::user_object<coord_type> user_object_type;
typedef db::box<coord_type> box_type;
typedef db::array<box_type, unit_trans_type> box_array_type;
typedef db::box<coord_type, coord_traits<coord_type>::short_coord_type> short_box_type;
typedef db::array<short_box_type, unit_trans_type> short_box_array_type;
typedef db::point<coord_type> point_type;
typedef db::generic_polygon_edge_iterator<coord_type> polygon_edge_iterator;
typedef db::generic_point_iterator<coord_type> point_iterator;
typedef tl::reuse_vector<db::polygon<coord_type> >::const_iterator polygon_iter_type;
typedef tl::reuse_vector<db::simple_polygon<coord_type> >::const_iterator simple_polygon_iter_type;
typedef tl::reuse_vector<db::polygon_ref<polygon_type, disp_type> >::const_iterator polygon_ref_iter_type;
typedef tl::reuse_vector<db::polygon_ref<polygon_type, unit_trans_type> >::const_iterator polygon_ptr_iter_type;
typedef tl::reuse_vector<db::array<polygon_ptr_type, disp_type> >::const_iterator polygon_ptr_array_iter_type;
typedef tl::reuse_vector<db::polygon_ref<simple_polygon_type, disp_type> >::const_iterator simple_polygon_ref_iter_type;
typedef tl::reuse_vector<db::polygon_ref<simple_polygon_type, unit_trans_type> >::const_iterator simple_polygon_ptr_iter_type;
typedef tl::reuse_vector<db::array<simple_polygon_ptr_type, disp_type> >::const_iterator simple_polygon_ptr_array_iter_type;
typedef tl::reuse_vector<db::path<coord_type> >::const_iterator path_iter_type;
typedef tl::reuse_vector<db::path_ref<path_type, disp_type> >::const_iterator path_ref_iter_type;
typedef tl::reuse_vector<db::path_ref<path_type, unit_trans_type> >::const_iterator path_ptr_iter_type;
typedef tl::reuse_vector<db::array<path_ptr_type, disp_type> >::const_iterator path_ptr_array_iter_type;
typedef tl::reuse_vector<db::edge<coord_type> >::const_iterator edge_iter_type;
typedef tl::reuse_vector<db::text<coord_type> >::const_iterator text_iter_type;
typedef tl::reuse_vector<db::text_ref<text_type, disp_type> >::const_iterator text_ref_iter_type;
typedef tl::reuse_vector<db::text_ref<text_type, unit_trans_type> >::const_iterator text_ptr_iter_type;
typedef tl::reuse_vector<db::array<text_ptr_type, disp_type> >::const_iterator text_ptr_array_iter_type;
typedef tl::reuse_vector<db::user_object<coord_type> >::const_iterator user_object_iter_type;
typedef tl::reuse_vector<db::box<coord_type> >::const_iterator box_iter_type;
typedef tl::reuse_vector<db::array<box_type, unit_trans_type> >::const_iterator box_array_iter_type;
typedef tl::reuse_vector<db::box<coord_type, coord_traits<coord_type>::short_coord_type> >::const_iterator short_box_iter_type;
typedef tl::reuse_vector<db::array<short_box_type, unit_trans_type> >::const_iterator short_box_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::polygon<coord_type> > >::const_iterator ppolygon_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::simple_polygon<coord_type> > >::const_iterator psimple_polygon_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::polygon_ref<polygon_type, disp_type> > >::const_iterator ppolygon_ref_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::polygon_ref<polygon_type, unit_trans_type> > >::const_iterator ppolygon_ptr_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<polygon_ptr_type, disp_type> > >::const_iterator ppolygon_ptr_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::polygon_ref<simple_polygon_type, disp_type> > >::const_iterator psimple_polygon_ref_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::polygon_ref<simple_polygon_type, unit_trans_type> > >::const_iterator psimple_polygon_ptr_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<simple_polygon_ptr_type, disp_type> > >::const_iterator psimple_polygon_ptr_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::path<coord_type> > >::const_iterator ppath_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::path_ref<path_type, disp_type> > >::const_iterator ppath_ref_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::path_ref<path_type, unit_trans_type> > >::const_iterator ppath_ptr_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<path_ptr_type, disp_type> > >::const_iterator ppath_ptr_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::edge<coord_type> > >::const_iterator pedge_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::text<coord_type> > >::const_iterator ptext_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::text_ref<text_type, disp_type> > >::const_iterator ptext_ref_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::text_ref<text_type, unit_trans_type> > >::const_iterator ptext_ptr_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<text_ptr_type, disp_type> > >::const_iterator ptext_ptr_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::user_object<coord_type> > >::const_iterator puser_object_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::box<coord_type> > >::const_iterator pbox_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<box_type, unit_trans_type> > >::const_iterator pbox_array_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::box<coord_type, coord_traits<coord_type>::short_coord_type> > >::const_iterator pshort_box_iter_type;
typedef tl::reuse_vector<db::object_with_properties<db::array<short_box_type, unit_trans_type> > >::const_iterator pshort_box_array_iter_type;
// Hint: in the following enum it is important that the ArrayMember types come *after*
// the non-member types. See db::shapes::erase with multi-shape erase capabilities.
enum object_type {
Null,
Polygon,
PolygonRef,
PolygonPtrArray,
PolygonPtrArrayMember,
SimplePolygon,
SimplePolygonRef,
SimplePolygonPtrArray,
SimplePolygonPtrArrayMember,
Edge,
Path,
PathRef,
PathPtrArray,
PathPtrArrayMember,
Box,
BoxArray,
BoxArrayMember,
ShortBox,
ShortBoxArray,
ShortBoxArrayMember,
Text,
TextRef,
TextPtrArray,
TextPtrArrayMember,
UserObject
};
/**
* @brief Construct a shape proxy as a null object
*/
Shape ()
: mp_shapes (0), m_with_props (false), m_stable (false), m_type (Null)
{
m_generic.any = 0;
}
/**
* @brief Construct as a proxy to a certain object
*/
template <class Obj>
Shape (const db::Shapes *shapes, const Obj &obj)
: mp_shapes (const_cast<db::Shapes *> (shapes)), m_with_props (false), m_stable (false)
{
typename Obj::tag tag = typename Obj::tag ();
init (tag);
m_generic.any = &obj;
}
/**
* @brief Construct as a proxy to a certain object
*/
template <class Obj>
Shape (db::Shapes *shapes, const Obj &obj)
: mp_shapes (shapes), m_with_props (false), m_stable (false)
{
typename Obj::tag tag = typename Obj::tag ();
init (tag);
m_generic.any = &obj;
}
/**
* @brief Construct as a proxy to a certain object
*
* This form will copy the object itself. A temporary object may be passed to "obj".
* An implementation is provided only for the array types
*
* Hint: there is no "const shape reference" currently and having one would mean
* we would probably create too much constness. Hence we use const_cast to convert it
* to a non-const one.
*/
template <class Obj, class Trans>
Shape (const db::Shapes *shapes, const Obj &obj, const Trans &trans)
: mp_shapes (const_cast<db::Shapes *> (shapes)), m_with_props (false), m_stable (false)
{
typename Obj::tag tag = typename Obj::tag ();
init_member (tag, trans_type (trans));
m_generic.any = &obj;
}
/**
* @brief Construct as a proxy to a certain object
*
* This form will copy the object itself. A temporary object may be passed to "obj".
* An implementation is provided only for the array types
*/
template <class Obj, class Trans>
Shape (db::Shapes *shapes, const Obj &obj, const Trans &trans)
: mp_shapes (shapes), m_with_props (false), m_stable (false)
{
typename Obj::tag tag = typename Obj::tag ();
init_member (tag, trans_type (trans));
m_generic.any = &obj;
}
/**
* @brief Construct as a proxy to a certain object given by an iterator
*
* Hint: there is no "const shape reference" currently and having one would mean
* we would probably create too much constness. Hence we use const_cast to convert it
* to a non-const one.
*/
template <class Obj>
Shape (const db::Shapes *shapes, const tl::reuse_vector_const_iterator<Obj> &tree_iter)
: mp_shapes (const_cast<db::Shapes *> (shapes)), m_with_props (false), m_stable (true)
{
typename Obj::tag tag = typename Obj::tag ();
// this sets the type and potentially m_with_props:
init (tag);
// HINT: we assume that we do not need an destructor for that iterator ..
new ((char *) m_generic.iter) typename tl::reuse_vector<Obj>::const_iterator (tree_iter);
}
/**
* @brief Construct as a proxy to a certain object given by an iterator
*/
template <class Obj>
Shape (db::Shapes *shapes, const tl::reuse_vector_const_iterator<Obj> &tree_iter)
: mp_shapes (shapes), m_with_props (false), m_stable (true)
{
typename Obj::tag tag = typename Obj::tag ();
// this sets the type and potentially m_with_props:
init (tag);
// HINT: we assume that we do not need an destructor for that iterator ..
new ((char *) m_generic.iter) typename tl::reuse_vector<Obj>::const_iterator (tree_iter);
}
/**
* @brief Construct as a proxy to a certain object given by an iterator
*
* Hint: there is no "const shape reference" currently and having one would mean
* we would probably create too much constness. Hence we use const_cast to convert it
* to a non-const one.
*/
template <class Obj, class Trans>
Shape (const db::Shapes *shapes, const tl::reuse_vector_const_iterator<Obj> &tree_iter, const Trans &trans)
: mp_shapes (const_cast<db::Shapes *> (shapes)), m_with_props (false), m_stable (true)
{
typename Obj::tag tag = typename Obj::tag ();
// this sets the type and potentially m_with_props:
init_member (tag, trans_type (trans));
// HINT: we assume that we do not need an destructor for that iterator ..
new ((char *) m_generic.iter) typename tl::reuse_vector<Obj>::const_iterator (tree_iter);
}
/**
* @brief Construct as a proxy to a certain object given by an iterator
*/
template <class Obj, class Trans>
Shape (db::Shapes *shapes, const tl::reuse_vector_const_iterator<Obj> &tree_iter, const Trans &trans)
: mp_shapes (shapes), m_with_props (false), m_stable (true)
{
typename Obj::tag tag = typename Obj::tag ();
// this sets the type and potentially m_with_props:
init_member (tag, trans_type (trans));
// HINT: we assume that we do not need an destructor for that iterator ..
new ((char *) m_generic.iter) typename tl::reuse_vector<Obj>::const_iterator (tree_iter);
}
/**
* @brief Returns the shape container this reference points into
*
* The returned value can be 0 indicating that there is no container.
*/
db::Shapes *shapes () const
{
return mp_shapes;
}
/**
* @brief Construct a shape proxy as a shape with properties
*
* This forwards the initialisation to the basic shape type.
*/
template <class Sh>
void init (db::object_tag< db::object_with_properties<Sh> >)
{
typename Sh::tag basic_tag = typename Sh::tag ();
init (basic_tag);
m_with_props = true;
}
/**
* @brief Construct a shape proxy as a shape with properties for an array member
*
* This form will copy the object itself. A temporary object may be passed to "obj".
* An implementation is provided only for a few types.
* This forwards the initialisation to the basic shape type.
*/
template <class Sh, class Trans>
void init_member (db::object_tag< db::object_with_properties<Sh> >, const Trans &trans)
{
typename Sh::tag tag = typename Sh::tag ();
init_member (tag, trans_type (trans));
m_with_props = true;
}
/**
* @brief Construct a shape proxy as a reference to a polygon
*/
void init (polygon_type::tag)
{
m_type = Polygon;
}
/**
* @brief Construct a shape proxy as a reference to a polygon reference
*/
void init (polygon_ref_type::tag)
{
m_type = PolygonRef;
}
/**
* @brief Construct a shape proxy as a reference to a polygon array member
*/
void init_member (polygon_ptr_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = PolygonPtrArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a polygon reference array
*/
void init (polygon_ptr_array_type::tag)
{
m_type = PolygonPtrArray;
}
/**
* @brief Construct a shape proxy as a reference to a simple olygon
*/
void init (simple_polygon_type::tag)
{
m_type = SimplePolygon;
}
/**
* @brief Construct a shape proxy as a reference to a polygon reference
*/
void init (simple_polygon_ref_type::tag)
{
m_type = SimplePolygonRef;
}
/**
* @brief Construct a shape proxy as a reference to a simple polygon array member
*/
void init_member (simple_polygon_ptr_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = SimplePolygonPtrArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a simple polygon reference array
*/
void init (simple_polygon_ptr_array_type::tag)
{
m_type = SimplePolygonPtrArray;
}
/**
* @brief Construct a shape proxy as a reference to a path
*/
void init (path_type::tag)
{
m_type = Path;
}
/**
* @brief Construct a shape proxy as a reference to a path reference
*/
void init (path_ref_type::tag)
{
m_type = PathRef;
}
/**
* @brief Construct a shape proxy as a reference to a path array member
*/
void init_member (path_ptr_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = PathPtrArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a path reference array
*/
void init (path_ptr_array_type::tag)
{
m_type = PathPtrArray;
}
/**
* @brief Construct a shape proxy as a reference to a text
*/
void init (text_type::tag)
{
m_type = Text;
}
/**
* @brief Construct a shape proxy as a reference to a text reference
*/
void init (text_ref_type::tag)
{
m_type = TextRef;
}
/**
* @brief Construct a shape proxy as a reference to a path array member
*/
void init_member (text_ptr_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = TextPtrArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a text reference array
*/
void init (text_ptr_array_type::tag)
{
m_type = TextPtrArray;
}
/**
* @brief Construct a shape proxy as a reference to a edge
*/
void init (edge_type::tag)
{
m_type = Edge;
}
/**
* @brief Construct a shape proxy as a reference to a box
*/
void init (box_type::tag)
{
m_type = Box;
}
/**
* @brief Construct a shape proxy as a reference to a box array member
*/
void init_member (box_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = BoxArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a box array
*/
void init (box_array_type::tag)
{
m_type = BoxArray;
}
/**
* @brief Construct a shape proxy as a reference to a small box
*/
void init (short_box_type::tag)
{
m_type = ShortBox;
}
/**
* @brief Construct a shape proxy as a reference to a box array member
*/
void init_member (short_box_array_type::tag, const trans_type &trans)
{
m_trans = trans;
m_type = ShortBoxArrayMember;
}
/**
* @brief Construct a shape proxy as a reference to a box array
*/
void init (short_box_array_type::tag)
{
m_type = ShortBoxArray;
}
/**
* @brief Construct a shape proxy as a reference to a user object
*/
void init (user_object_type::tag)
{
m_type = UserObject;
}
/**
* @brief Determine, if the shape is of "object_with_properties" type.
*
* Usually, the properties id (see prop_id()) should be used.
*
* @return true, if the shape is of "object_with_properties<Sh> type".
*/
bool with_props () const
{
return m_with_props;
}
/**
* @brief Get the properties Id associated with the shape
*/
db::properties_id_type prop_id () const;
/**
* @brief Check, if the shape is associated with a properties Id
*/
bool has_prop_id () const
{
return m_with_props;
}
/**
* @brief Create the "begin" point iterator
*
* This method applies to paths.
*/
point_iterator begin_point () const;
/**
* @brief Create the "end" point iterator
*
* This method applies to paths.
*/
point_iterator end_point () const;
/**
* @brief Create the "begin" hull point iterator
*
* This method applies to polygons.
*/
point_iterator begin_hull () const;
/**
* @brief Create the "end" hull point iterator
*
* This method applies to polygons.
*/
point_iterator end_hull () const;
/**
* @brief Create the "begin" hole point iterator
*
* This method applies to polygons.
* Simple polygons deliver an empty sequence.
*
* @param hole The hole index (see holes () method)
*/
point_iterator begin_hole (unsigned int hole) const;
/**
* @brief Create the "end" hole point iterator
*
* This method applies to polygons.
* Simple polygons deliver an empty sequence.
*
* @param hole The hole index (see holes () method)
*/
point_iterator end_hole (unsigned int hole) const;
/**
* @brief Return the number of holes
*
* This method applies to polygons.
* Simple polygons deliver a zero value.
*/
unsigned int holes () const;
/**
* @brief Create and return an edge iterator
*/
polygon_edge_iterator begin_edge () const;
/**
* @brief Create and return an edge iterator for the given contour
* If the object is a polygon, a contour of 0 will deliver the
* edges of the hull and higher contours will deliver the edges of holes.
*/
polygon_edge_iterator begin_edge (unsigned int c) const;
/**
* @brief Return the type of the shape reference
*/
object_type type () const
{
return m_type;
}
/**
* @brief Test if the shape proxy is a null object
*/
bool is_null () const
{
return m_type == Null;
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const polygon_type *basic_ptr (polygon_type::tag) const
{
tl_assert (m_type == Polygon);
if (m_stable) {
return m_with_props ? &**(((ppolygon_iter_type *) m_generic.iter)) : &**(((polygon_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppolygon : m_generic.polygon;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const simple_polygon_type *basic_ptr (simple_polygon_type::tag) const
{
tl_assert (m_type == SimplePolygon);
if (m_stable) {
return m_with_props ? &**(((psimple_polygon_iter_type *) m_generic.iter)) : &**(((simple_polygon_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.psimple_polygon : m_generic.simple_polygon;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const polygon_ref_type *basic_ptr (polygon_ref_type::tag) const
{
tl_assert (m_type == PolygonRef);
if (m_stable) {
return m_with_props ? &**(((ppolygon_ref_iter_type *) m_generic.iter)) : &**(((polygon_ref_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppolygon_ref : m_generic.polygon_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const polygon_ptr_array_type *basic_ptr (polygon_ptr_array_type::tag) const
{
tl_assert (m_type == PolygonPtrArray || m_type == PolygonPtrArrayMember);
if (m_stable) {
return m_with_props ? &**(((ppolygon_ptr_array_iter_type *) m_generic.iter)) : &**(((polygon_ptr_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppolygon_aref : m_generic.polygon_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const simple_polygon_ref_type *basic_ptr (simple_polygon_ref_type::tag) const
{
tl_assert (m_type == SimplePolygonRef);
if (m_stable) {
return m_with_props ? &**(((psimple_polygon_ref_iter_type *) m_generic.iter)) : &**(((simple_polygon_ref_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.psimple_polygon_ref : m_generic.simple_polygon_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const simple_polygon_ptr_array_type *basic_ptr (simple_polygon_ptr_array_type::tag) const
{
tl_assert (m_type == SimplePolygonPtrArray || m_type == SimplePolygonPtrArrayMember);
if (m_stable) {
return m_with_props ? &**(((psimple_polygon_ptr_array_iter_type *) m_generic.iter)) : &**(((simple_polygon_ptr_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.psimple_polygon_aref : m_generic.simple_polygon_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const path_type *basic_ptr (path_type::tag) const
{
tl_assert (m_type == Path);
if (m_stable) {
return m_with_props ? &**(((ppath_iter_type *) m_generic.iter)) : &**(((path_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppath : m_generic.path;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const path_ref_type *basic_ptr (path_ref_type::tag) const
{
tl_assert (m_type == PathRef);
if (m_stable) {
return m_with_props ? &**(((ppath_ref_iter_type *) m_generic.iter)) : &**(((path_ref_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppath_ref : m_generic.path_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const path_ptr_array_type *basic_ptr (path_ptr_array_type::tag) const
{
tl_assert (m_type == PathPtrArray || m_type == PathPtrArrayMember);
if (m_stable) {
return m_with_props ? &**(((ppath_ptr_array_iter_type *) m_generic.iter)) : &**(((path_ptr_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ppath_aref : m_generic.path_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const edge_type *basic_ptr (edge_type::tag) const
{
tl_assert (m_type == Edge);
if (m_stable) {
return m_with_props ? &**(((pedge_iter_type *) m_generic.iter)) : &**(((edge_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.pedge : m_generic.edge;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const text_type *basic_ptr (text_type::tag) const
{
tl_assert (m_type == Text);
if (m_stable) {
return m_with_props ? &**(((ptext_iter_type *) m_generic.iter)) : &**(((text_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ptext : m_generic.text;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const text_ref_type *basic_ptr (text_ref_type::tag) const
{
tl_assert (m_type == TextRef);
if (m_stable) {
return m_with_props ? &**(((ptext_ref_iter_type *) m_generic.iter)) : &**(((text_ref_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ptext_ref : m_generic.text_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const text_ptr_array_type *basic_ptr (text_ptr_array_type::tag) const
{
tl_assert (m_type == TextPtrArray || m_type == TextPtrArrayMember);
if (m_stable) {
return m_with_props ? &**(((ptext_ptr_array_iter_type *) m_generic.iter)) : &**(((text_ptr_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.ptext_aref : m_generic.text_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const user_object_type *basic_ptr (user_object_type::tag) const
{
tl_assert (m_type == UserObject);
if (m_stable) {
return m_with_props ? &**(((puser_object_iter_type *) m_generic.iter)) : &**(((user_object_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.puser_object : m_generic.user_object;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const box_type *basic_ptr (box_type::tag) const
{
tl_assert (m_type == Box);
if (m_stable) {
return m_with_props ? &**(((pbox_iter_type *) m_generic.iter)) : &**(((box_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.pbox : m_generic.box;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const box_array_type *basic_ptr (box_array_type::tag) const
{
tl_assert (m_type == BoxArray || m_type == BoxArrayMember);
if (m_stable) {
return m_with_props ? &**(((pbox_array_iter_type *) m_generic.iter)) : &**(((box_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.pbox_array : m_generic.box_array;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const short_box_type *basic_ptr (short_box_type::tag) const
{
tl_assert (m_type == ShortBox);
if (m_stable) {
return m_with_props ? &**(((pshort_box_iter_type *) m_generic.iter)) : &**(((short_box_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.pshort_box : m_generic.short_box;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const short_box_array_type *basic_ptr (short_box_array_type::tag) const
{
tl_assert (m_type == ShortBoxArray || m_type == ShortBoxArrayMember);
if (m_stable) {
return m_with_props ? &**(((pshort_box_array_iter_type *) m_generic.iter)) : &**(((short_box_array_iter_type *) m_generic.iter));
} else {
return m_with_props ? m_generic.pshort_box_array : m_generic.short_box_array;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<polygon_type> *basic_ptr (db::object_with_properties<polygon_type>::tag) const
{
tl_assert (m_type == Polygon);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppolygon_iter_type *) m_generic.iter));
} else {
return m_generic.ppolygon;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<simple_polygon_type> *basic_ptr (db::object_with_properties<simple_polygon_type>::tag) const
{
tl_assert (m_type == SimplePolygon);
tl_assert (m_with_props);
if (m_stable) {
return &**(((psimple_polygon_iter_type *) m_generic.iter));
} else {
return m_generic.psimple_polygon;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<polygon_ref_type> *basic_ptr (db::object_with_properties<polygon_ref_type>::tag) const
{
tl_assert (m_type == PolygonRef);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppolygon_ref_iter_type *) m_generic.iter));
} else {
return m_generic.ppolygon_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<polygon_ptr_array_type> *basic_ptr (db::object_with_properties<polygon_ptr_array_type>::tag) const
{
tl_assert (m_type == PolygonPtrArray || m_type == PolygonPtrArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppolygon_ptr_array_iter_type *) m_generic.iter));
} else {
return m_generic.ppolygon_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<simple_polygon_ref_type> *basic_ptr (db::object_with_properties<simple_polygon_ref_type>::tag) const
{
tl_assert (m_type == SimplePolygonRef);
tl_assert (m_with_props);
if (m_stable) {
return &**(((psimple_polygon_ref_iter_type *) m_generic.iter));
} else {
return m_generic.psimple_polygon_ref;
}
}
const db::object_with_properties<simple_polygon_ptr_array_type> *basic_ptr (db::object_with_properties<simple_polygon_ptr_array_type>::tag) const
{
tl_assert (m_type == SimplePolygonPtrArray || m_type == SimplePolygonPtrArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((psimple_polygon_ptr_array_iter_type *) m_generic.iter));
} else {
return m_generic.psimple_polygon_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<path_type> *basic_ptr (db::object_with_properties<path_type>::tag) const
{
tl_assert (m_type == Path);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppath_iter_type *) m_generic.iter));
} else {
return m_generic.ppath;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<path_ref_type> *basic_ptr (db::object_with_properties<path_ref_type>::tag) const
{
tl_assert (m_type == PathRef);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppath_ref_iter_type *) m_generic.iter));
} else {
return m_generic.ppath_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<path_ptr_array_type> *basic_ptr (db::object_with_properties<path_ptr_array_type>::tag) const
{
tl_assert (m_type == PathPtrArray || m_type == PathPtrArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ppath_ptr_array_iter_type *) m_generic.iter));
} else {
return m_generic.ppath_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<edge_type> *basic_ptr (db::object_with_properties<edge_type>::tag) const
{
tl_assert (m_type == Edge);
tl_assert (m_with_props);
if (m_stable) {
return &**(((pedge_iter_type *) m_generic.iter));
} else {
return m_generic.pedge;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<text_type> *basic_ptr (db::object_with_properties<text_type>::tag) const
{
tl_assert (m_type == Text);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ptext_iter_type *) m_generic.iter));
} else {
return m_generic.ptext;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<text_ref_type> *basic_ptr (db::object_with_properties<text_ref_type>::tag) const
{
tl_assert (m_type == TextRef);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ptext_ref_iter_type *) m_generic.iter));
} else {
return m_generic.ptext_ref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<text_ptr_array_type> *basic_ptr (db::object_with_properties<text_ptr_array_type>::tag) const
{
tl_assert (m_type == TextPtrArray || m_type == TextPtrArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((ptext_ptr_array_iter_type *) m_generic.iter));
} else {
return m_generic.ptext_aref;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<user_object_type> *basic_ptr (db::object_with_properties<user_object_type>::tag) const
{
tl_assert (m_type == UserObject);
tl_assert (m_with_props);
if (m_stable) {
return &**(((puser_object_iter_type *) m_generic.iter));
} else {
return m_generic.puser_object;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<box_type> *basic_ptr (db::object_with_properties<box_type>::tag) const
{
tl_assert (m_type == Box);
tl_assert (m_with_props);
if (m_stable) {
return &**(((pbox_iter_type *) m_generic.iter));
} else {
return m_generic.pbox;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<box_array_type> *basic_ptr (db::object_with_properties<box_array_type>::tag) const
{
tl_assert (m_type == BoxArray || m_type == BoxArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((pbox_array_iter_type *) m_generic.iter));
} else {
return m_generic.pbox_array;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<short_box_type> *basic_ptr (db::object_with_properties<short_box_type>::tag) const
{
tl_assert (m_type == ShortBox);
tl_assert (m_with_props);
if (m_stable) {
return &**(((pshort_box_iter_type *) m_generic.iter));
} else {
return m_generic.pshort_box;
}
}
/**
* @brief Return the actual object that this shape reference is pointing to for objects with properties
*
* This is a generalisation of the polygon (), etc. methods using a tag to identify the
* target object.
*/
const db::object_with_properties<short_box_array_type> *basic_ptr (db::object_with_properties<short_box_array_type>::tag) const
{
tl_assert (m_type == ShortBoxArray || m_type == ShortBoxArrayMember);
tl_assert (m_with_props);
if (m_stable) {
return &**(((pshort_box_array_iter_type *) m_generic.iter));
} else {
return m_generic.pshort_box_array;
}
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
polygon_iter_type basic_iter (polygon_type::tag) const
{
tl_assert (m_type == Polygon && ! m_with_props);
return *(((polygon_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
simple_polygon_iter_type basic_iter (simple_polygon_type::tag) const
{
tl_assert (m_type == SimplePolygon && ! m_with_props);
return *(((simple_polygon_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
polygon_ref_iter_type basic_iter (polygon_ref_type::tag) const
{
tl_assert (m_type == PolygonRef && ! m_with_props);
return *(((polygon_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
polygon_ptr_array_iter_type basic_iter (polygon_ptr_array_type::tag) const
{
tl_assert ((m_type == PolygonPtrArray || m_type == PolygonPtrArrayMember) && ! m_with_props);
return *(((polygon_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
simple_polygon_ref_iter_type basic_iter (simple_polygon_ref_type::tag) const
{
tl_assert (m_type == SimplePolygonRef && ! m_with_props);
return *(((simple_polygon_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
simple_polygon_ptr_array_iter_type basic_iter (simple_polygon_ptr_array_type::tag) const
{
tl_assert ((m_type == SimplePolygonPtrArray || m_type == SimplePolygonPtrArrayMember) && ! m_with_props);
return *(((simple_polygon_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
path_iter_type basic_iter (path_type::tag) const
{
tl_assert (m_type == Path && ! m_with_props);
return *(((path_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
path_ref_iter_type basic_iter (path_ref_type::tag) const
{
tl_assert (m_type == PathRef && ! m_with_props);
return *(((path_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
path_ptr_array_iter_type basic_iter (path_ptr_array_type::tag) const
{
tl_assert ((m_type == PathPtrArray || m_type == PathPtrArrayMember) && ! m_with_props);
return *(((path_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
edge_iter_type basic_iter (edge_type::tag) const
{
tl_assert (m_type == Edge && ! m_with_props);
return *(((edge_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
text_iter_type basic_iter (text_type::tag) const
{
tl_assert (m_type == Text && ! m_with_props);
return *(((text_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
text_ref_iter_type basic_iter (text_ref_type::tag) const
{
tl_assert (m_type == TextRef && ! m_with_props);
return *(((text_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
text_ptr_array_iter_type basic_iter (text_ptr_array_type::tag) const
{
tl_assert ((m_type == TextPtrArray || m_type == TextPtrArrayMember) && ! m_with_props);
return *(((text_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
user_object_iter_type basic_iter (user_object_type::tag) const
{
tl_assert (m_type == UserObject && ! m_with_props);
return *(((user_object_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
box_iter_type basic_iter (box_type::tag) const
{
tl_assert (m_type == Box && ! m_with_props);
return *(((box_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
box_array_iter_type basic_iter (box_array_type::tag) const
{
tl_assert ((m_type == BoxArray || m_type == BoxArrayMember) && ! m_with_props);
return *(((box_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
short_box_iter_type basic_iter (short_box_type::tag) const
{
tl_assert (m_type == ShortBox && ! m_with_props);
return *(((short_box_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag
*/
short_box_array_iter_type basic_iter (short_box_array_type::tag) const
{
tl_assert ((m_type == ShortBoxArray || m_type == ShortBoxArrayMember) && ! m_with_props);
return *(((short_box_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppolygon_iter_type basic_iter (db::object_with_properties<polygon_type>::tag) const
{
tl_assert (m_type == Polygon && m_with_props);
return *(((ppolygon_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
psimple_polygon_iter_type basic_iter (db::object_with_properties<simple_polygon_type>::tag) const
{
tl_assert (m_type == SimplePolygon && m_with_props);
return *(((psimple_polygon_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppolygon_ref_iter_type basic_iter (db::object_with_properties<polygon_ref_type>::tag) const
{
tl_assert (m_type == PolygonRef && m_with_props);
return *(((ppolygon_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppolygon_ptr_array_iter_type basic_iter (db::object_with_properties<polygon_ptr_array_type>::tag) const
{
tl_assert ((m_type == PolygonPtrArray || m_type == PolygonPtrArrayMember) && m_with_props);
return *(((ppolygon_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
psimple_polygon_ref_iter_type basic_iter (db::object_with_properties<simple_polygon_ref_type>::tag) const
{
tl_assert (m_type == SimplePolygonRef && m_with_props);
return *(((psimple_polygon_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
psimple_polygon_ptr_array_iter_type basic_iter (db::object_with_properties<simple_polygon_ptr_array_type>::tag) const
{
tl_assert ((m_type == SimplePolygonPtrArray || m_type == SimplePolygonPtrArrayMember) && m_with_props);
return *(((psimple_polygon_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppath_iter_type basic_iter (db::object_with_properties<path_type>::tag) const
{
tl_assert (m_type == Path && m_with_props);
return *(((ppath_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppath_ref_iter_type basic_iter (db::object_with_properties<path_ref_type>::tag) const
{
tl_assert (m_type == PathRef && m_with_props);
return *(((ppath_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ppath_ptr_array_iter_type basic_iter (db::object_with_properties<path_ptr_array_type>::tag) const
{
tl_assert ((m_type == PathPtrArray || m_type == PathPtrArrayMember) && m_with_props);
return *(((ppath_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
pedge_iter_type basic_iter (db::object_with_properties<edge_type>::tag) const
{
tl_assert (m_type == Edge && m_with_props);
return *(((pedge_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ptext_iter_type basic_iter (db::object_with_properties<text_type>::tag) const
{
tl_assert (m_type == Text && m_with_props);
return *(((ptext_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ptext_ref_iter_type basic_iter (db::object_with_properties<text_ref_type>::tag) const
{
tl_assert (m_type == TextRef && m_with_props);
return *(((ptext_ref_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
ptext_ptr_array_iter_type basic_iter (db::object_with_properties<text_ptr_array_type>::tag) const
{
tl_assert ((m_type == TextPtrArray || m_type == TextPtrArrayMember) && m_with_props);
return *(((ptext_ptr_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
puser_object_iter_type basic_iter (db::object_with_properties<user_object_type>::tag) const
{
tl_assert (m_type == UserObject && m_with_props);
return *(((puser_object_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
pbox_iter_type basic_iter (db::object_with_properties<box_type>::tag) const
{
tl_assert (m_type == Box && m_with_props);
return *(((pbox_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
pbox_array_iter_type basic_iter (db::object_with_properties<box_array_type>::tag) const
{
tl_assert ((m_type == BoxArray || m_type == BoxArrayMember) && m_with_props);
return *(((pbox_array_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
pshort_box_iter_type basic_iter (db::object_with_properties<short_box_type>::tag) const
{
tl_assert (m_type == ShortBox && m_with_props);
return *(((pshort_box_iter_type *) m_generic.iter));
}
/**
* @brief Return the iterator (in stable reference mode) by tag for objects with properties
*/
pshort_box_array_iter_type basic_iter (db::object_with_properties<short_box_array_type>::tag) const
{
tl_assert ((m_type == ShortBoxArray || m_type == ShortBoxArrayMember) && m_with_props);
return *(((pshort_box_array_iter_type *) m_generic.iter));
}
/**
* @brief Return a reference to the polygon if one is referenced
*/
const polygon_type &polygon () const
{
return *basic_ptr (polygon_type::tag ());
}
/**
* @brief Return a polygon reference if one is referenced
*/
polygon_ref_type polygon_ref () const;
/**
* @brief Return a reference to the simple polygon if one is referenced
*/
const simple_polygon_type &simple_polygon () const
{
return *basic_ptr (simple_polygon_type::tag ());
}
/**
* @brief Return a simple polygon reference if one is referenced
*/
simple_polygon_ref_type simple_polygon_ref () const;
/**
* @brief Test if the shape proxy points to a polygon
*/
bool is_polygon () const
{
return (m_type == Polygon || m_type == PolygonRef || m_type == PolygonPtrArrayMember ||
m_type == SimplePolygon || m_type == SimplePolygonRef || m_type == SimplePolygonPtrArrayMember);
}
/**
* @brief Instantiate the polygon object
*
* If a polygon is referenced, this object is instantiated
* by this method. Paths are converted to polygons. Boxes are also converted.
* Returns true, if the conversion was successful.
*/
bool polygon (polygon_type &p) const;
/**
* @brief Alias for polymorphic expansion
* Returns true, if the conversion was successful.
*/
bool instantiate (polygon_type &p) const
{
return polygon (p);
}
/**
* @brief Test if the shape proxy points to a simple polygon
*/
bool is_simple_polygon () const
{
return (m_type == SimplePolygon || m_type == SimplePolygonRef || m_type == SimplePolygonPtrArrayMember);
}
/**
* @brief Instantiate the simple polygon object
*
* If a simple polygon is referenced, this object is instantiated
* by this method. Paths are converted to polygons. Boxes are also converted.
* Returns true, if the conversion was successful.
*/
bool simple_polygon (simple_polygon_type &p) const;
/**
* @brief Alias for polymorphic expansion
* Returns true, if the conversion was successful.
*/
bool instantiate (simple_polygon_type &p) const
{
return simple_polygon (p);
}
/**
* @brief Return a reference to the path if one is referenced
*/
const path_type &path () const
{
return *basic_ptr (path_type::tag ());
}
/**
* @brief Return a path reference if one is referenced
*/
path_ref_type path_ref () const;
/**
* @brief Test if the shape proxy points to a path
*/
bool is_path () const
{
return (m_type == Path || m_type == PathRef || m_type == PathPtrArrayMember);
}
/**
* @brief Obtain the path length
*
* Applies to paths only. Will assert if not a path.
*/
distance_type path_length () const;
/**
* @brief Obtain the path width
*
* Applies to paths only. Will assert if not a path.
*/
coord_type path_width () const;
/**
* @brief Obtain the path extensions
*
* Applies to paths only. Will assert if not a path.
*
* @return A pair consisting of the begin and end extensions.
*/
std::pair<coord_type, coord_type> path_extensions () const;
/**
* @brief Obtain the round path flag
*
* Applies to paths only. Will assert if not a path.
*
* @return True, if the path has round ends
*/
bool round_path () const;
/**
* @brief Instantiate the path object
*
* If a path is referenced, this object is instantiated
* by this method.
* Returns true, if the conversion was successful.
*/
bool path (path_type &p) const;
/**
* @brief Alias for polymorphic expansion
*/
bool instantiate (path_type &p) const
{
return path (p);
}
/**
* @brief Return a reference to the edge if one is referenced
*/
const edge_type &edge () const
{
tl_assert (m_type == Edge);
return *basic_ptr (edge_type::tag ());
}
/**
* @brief Test if the shape proxy points to a edge
*/
bool is_edge () const
{
return (m_type == Edge);
}
/**
* @brief Instantiate the edge object
*
* If a edge is referenced, this object is instantiated
* by this method.
* Returns true, if the conversion was successful.
*/
bool edge (edge_type &e) const
{
if (is_edge ()) {
e = edge ();
return true;
} else {
return false;
}
}
/**
* @brief Alias for polymorphic expansion
* Returns true, if the conversion was successful.
*/
bool instantiate (edge_type &p) const
{
return edge (p);
}
/**
* @brief Return a reference to the text if one is referenced
*/
const text_type &text () const
{
return *basic_ptr (text_type::tag ());
}
/**
* @brief Return a text reference if one is referenced
*/
text_ref_type text_ref () const;
/**
* @brief Test if the shape proxy points to a text
*/
bool is_text () const
{
return (m_type == Text || m_type == TextRef || m_type == TextPtrArrayMember);
}
/**
* @brief Instantiate the text object
*
* If a text is referenced, this object is instantiated
* by this method.
* Returns true, if the conversion was successful
*/
bool text (text_type &t) const;
/**
* @brief Alias for polymorphic expansion
* Returns true, if the conversion was successful
*/
bool instantiate (text_type &p) const
{
return text (p);
}
/**
* @brief Obtain the text string
*
* Applies to texts only. Will assert if not a text.
*/
const char *text_string () const;
/**
* @brief Obtain the text transformation
*
* Applies to texts only. Will assert if not a text.
*/
text_type::trans_type text_trans () const;
/**
* @brief Obtain the text size
*
* Applies to texts only. Will assert if not a text.
*/
coord_type text_size () const;
/**
* @brief Obtain the text's font
*
* Applies to texts only. Will assert if not a text.
*/
db::Font text_font () const;
/**
* @brief Obtain the text's horizontal alignment
*
* Applies to texts only. Will assert if not a text.
*/
db::HAlign text_halign () const;
/**
* @brief Obtain the text's vertical alignment
*
* Applies to texts only. Will assert if not a text.
*/
db::VAlign text_valign () const;
/**
* @brief Return a box if one is referenced
*/
box_type box () const;
/**
* @brief Test if the shape proxy points to a box
*/
bool is_box () const
{
return (m_type == Box || m_type == ShortBox || m_type == BoxArrayMember || m_type == ShortBoxArrayMember);
}
/**
* @brief Instantiate the box object
*
* If a box is referenced, this object is instantiated
* by this method.
* Returns true, if the conversion was successful
*/
bool box (box_type &b) const
{
if (is_box ()) {
b = box ();
return true;
} else {
return false;
}
}
/**
* @brief Alias for polymorphic expansion
*/
bool instantiate (box_type &p) const
{
return box (p);
}
/**
* @brief Return a reference to the user object if one is referenced
*/
const user_object_type &user_object () const
{
return *basic_ptr (user_object_type::tag ());
}
/**
* @brief Test if the shape proxy points to a user object
*/
bool is_user_object () const
{
return (m_type == UserObject);
}
/**
* @brief Instantiate the user object
*
* If a user object is referenced, this object is instantiated
* by this method.
*/
void user_object (user_object_type &u) const
{
u = *basic_ptr (user_object_type::tag ());
}
/**
* @brief Compute the bounding box of the shape the is referenced
*/
box_type bbox () const;
/**
* @brief Compute the area of the shape
*/
area_type area () const;
/**
* @brief Compute the perimeter of the shape
*/
perimeter_type perimeter () const;
/**
* @brief Attribute that tells if the shape is member of an array
*
* In this case the shape is not a freestanding shape but one instance of an
* array shape.
*/
bool is_array_member () const
{
return m_type == PolygonPtrArrayMember ||
m_type == SimplePolygonPtrArrayMember ||
m_type == PathPtrArrayMember ||
m_type == BoxArrayMember ||
m_type == ShortBoxArrayMember ||
m_type == TextPtrArrayMember;
}
/**
* @brief Returns the array size if the shape references an array
*/
size_t array_size () const;
/**
* @brief Array instance member transformation
*
* This attribute is valid only if is_array_member is true.
* The transformation returned describes the relative transformation of the
* array member addressed.
*/
const trans_type &array_trans () const
{
return m_trans;
}
/**
* @brief inequality
*/
bool operator!= (const Shape &d) const
{
return ! operator== (d);
}
/**
* @brief equality
*
* Equality of shapes is not specified by the identity of the objects but by the
* identity of the pointers - both shapes must reference the same object.
*/
bool operator== (const Shape &d) const
{
if (m_type != d.m_type) {
return false;
}
if (m_stable) {
// do a byte-by-byte compare of the iterators:
// there are supposed to have the same size for all types, thus all bytes are
// supposed to be meaningful
for (unsigned int i = 0; i < sizeof (tl::reuse_vector<box_type>::const_iterator); ++i) {
if (m_generic.iter[i] != d.m_generic.iter[i]) {
return false;
}
}
} else {
if (m_generic.any != d.m_generic.any) {
return false;
}
}
return m_trans == d.m_trans;
}
/**
* @brief less-than operator
*
* Ordering of shapes is not specified by the identity of the objects but by the
* order of the pointers.
* Since pointers are volatile objects, the ordering is not strictly reproducable!
*/
bool operator< (const Shape &d) const
{
if (m_type != d.m_type) {
return m_type < d.m_type;
}
if (m_stable) {
// do a byte-by-byte compare of the iterators:
// there are supposed to have the same size for all types, thus all bytes are
// supposed to be meaningful
for (unsigned int i = 0; i < sizeof (tl::reuse_vector<box_type>::const_iterator); ++i) {
if (m_generic.iter[i] != d.m_generic.iter[i]) {
return m_generic.iter[i] < d.m_generic.iter[i];
}
}
} else {
if (m_generic.any != d.m_generic.any) {
return m_generic.any < d.m_generic.any;
}
}
return m_trans < d.m_trans;
}
size_t mem_used () const
{
return sizeof (*this);
}
size_t mem_reqd () const
{
return sizeof (*this);
}
/**
* @brief Convert to a string
*/
std::string to_string () const;
public:
friend class db::Shapes;
union generic {
const polygon_type *polygon;
const polygon_ref_type *polygon_ref;
const polygon_ptr_array_type *polygon_aref;
const simple_polygon_type *simple_polygon;
const simple_polygon_ref_type *simple_polygon_ref;
const simple_polygon_ptr_array_type *simple_polygon_aref;
const text_type *text;
const text_ref_type *text_ref;
const text_ptr_array_type *text_aref;
const edge_type *edge;
const path_type *path;
const path_ref_type *path_ref;
const path_ptr_array_type *path_aref;
const box_type *box;
const box_array_type *box_array;
const short_box_type *short_box;
const short_box_array_type *short_box_array;
const user_object_type *user_object;
const db::object_with_properties<polygon_type> *ppolygon;
const db::object_with_properties<polygon_ref_type> *ppolygon_ref;
const db::object_with_properties<polygon_ptr_array_type> *ppolygon_aref;
const db::object_with_properties<simple_polygon_type> *psimple_polygon;
const db::object_with_properties<simple_polygon_ref_type> *psimple_polygon_ref;
const db::object_with_properties<simple_polygon_ptr_array_type> *psimple_polygon_aref;
const db::object_with_properties<text_type> *ptext;
const db::object_with_properties<text_ref_type> *ptext_ref;
const db::object_with_properties<text_ptr_array_type> *ptext_aref;
const db::object_with_properties<edge_type> *pedge;
const db::object_with_properties<path_type> *ppath;
const db::object_with_properties<path_ref_type> *ppath_ref;
const db::object_with_properties<path_ptr_array_type> *ppath_aref;
const db::object_with_properties<box_type> *pbox;
const db::object_with_properties<box_array_type> *pbox_array;
const db::object_with_properties<short_box_type> *pshort_box;
const db::object_with_properties<short_box_array_type> *pshort_box_array;
const db::object_with_properties<user_object_type> *puser_object;
const void *any;
// all iterators have the same size - there is just one space for that
char iter [sizeof (tl::reuse_vector<box_type>::const_iterator)];
};
db::Shapes *mp_shapes;
generic m_generic;
trans_type m_trans;
bool m_with_props : 8;
bool m_stable : 8;
object_type m_type : 16;
};
template <class C>
size_t mem_used (const Shape &s)
{
return s.mem_used ();
}
template <class C>
size_t mem_reqd (const Shape &s)
{
return s.mem_reqd ();
}
} // namespace db
#endif