~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to include/ggl/core/access.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2009-09-13 00:52:12 UTC
  • mto: (1.2.7 upstream) (0.1.3 upstream) (3.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090913005212-pjecal8zxm07x0fj
ImportĀ upstreamĀ versionĀ 0.14+svnfixes~20090912

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Generic Geometry Library
 
2
//
 
3
// Copyright Bruno Lalande 2008, 2009
 
4
// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
 
5
// Use, modification and distribution is subject to the Boost Software License,
 
6
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 
7
// http://www.boost.org/LICENSE_1_0.txt)
 
8
 
 
9
#ifndef GGL_CORE_ACCESS_HPP
 
10
#define GGL_CORE_ACCESS_HPP
 
11
 
 
12
#include <cstddef>
 
13
 
 
14
#include <boost/type_traits/remove_const.hpp>
 
15
#include <boost/concept_check.hpp>
 
16
 
 
17
#include <ggl/core/coordinate_type.hpp>
 
18
#include <ggl/core/point_type.hpp>
 
19
#include <ggl/core/tag.hpp>
 
20
 
 
21
namespace ggl
 
22
{
 
23
 
 
24
const int min_corner = 0;
 
25
const int max_corner = 1;
 
26
 
 
27
namespace traits
 
28
{
 
29
 
 
30
/*!
 
31
    \brief Traits class which gives access (get,set) to points
 
32
    \ingroup traits
 
33
    \par Geometries:
 
34
        - point
 
35
        - n-sphere (circle,sphere) for their center
 
36
    \par Specializations should provide:
 
37
        - static inline T get<I>(const G&)
 
38
        - static inline void set<I>(G&, const T&)
 
39
    \tparam G geometry
 
40
*/
 
41
template <typename G>
 
42
struct access {};
 
43
 
 
44
 
 
45
/*!
 
46
    \brief Traits class defining "get" and "set" to get and set point coordinate values
 
47
    \tparam G geometry (box, segment)
 
48
    \tparam I index (min_corner/max_corner for box, 0/1 for segment)
 
49
    \tparam D dimension
 
50
    \par Geometries:
 
51
        - box
 
52
        - segment
 
53
    \par Specializations should provide:
 
54
        - static inline T get(const G&)
 
55
        - static inline void set(G&, const T&)
 
56
    \ingroup traits
 
57
*/
 
58
template <typename G, std::size_t I, std::size_t D>
 
59
struct indexed_access {};
 
60
 
 
61
 
 
62
/*!
 
63
    \brief Traits class, optional, indicating that the std-library should be used
 
64
    \details The default geometry (linestring, ring, multi*) follow std:: for
 
65
        its modifying operations (push_back, clear, size, resize, reserve, etc)
 
66
        If they NOT follow the std:: library they should specialize this traits
 
67
        class
 
68
    \ingroup traits
 
69
    \par Geometries:
 
70
        - linestring
 
71
        - linear_ring
 
72
    \par Specializations should provide:
 
73
        - value (defaults to true)
 
74
 */
 
75
template <typename G>
 
76
struct use_std
 
77
{
 
78
    static const bool value = true;
 
79
};
 
80
 
 
81
} // namespace traits
 
82
 
 
83
 
 
84
#ifndef DOXYGEN_NO_DISPATCH
 
85
namespace core_dispatch
 
86
{
 
87
template <typename Tag, typename G, typename T, std::size_t D>
 
88
struct access
 
89
{
 
90
    //static inline T get(const G& ) {}
 
91
    //static inline void set(G& g, const T& value) {}
 
92
};
 
93
 
 
94
template <typename Tag, typename G, typename T, std::size_t I, std::size_t D>
 
95
struct indexed_access
 
96
{
 
97
    //static inline T get(const G& ) {}
 
98
    //static inline void set(G& g, const T& value) {}
 
99
};
 
100
 
 
101
template <typename P, typename T, std::size_t D>
 
102
struct access<point_tag, P, T, D>
 
103
{
 
104
    static inline T get(const P& p)
 
105
    {
 
106
        return traits::access<P>::template get<D>(p);
 
107
    }
 
108
    static inline void set(P& p, const T& value)
 
109
    {
 
110
        traits::access<P>::template set<D>(p, value);
 
111
    }
 
112
};
 
113
 
 
114
template <typename S, typename T, std::size_t D>
 
115
struct access<nsphere_tag, S, T, D>
 
116
{
 
117
    static inline T get(const S& s)
 
118
    {
 
119
        return traits::access<S>::template get<D>(s);
 
120
    }
 
121
    static inline void set(S& s, const T& value)
 
122
    {
 
123
        traits::access<S>::template set<D>(s, value);
 
124
    }
 
125
};
 
126
 
 
127
template <typename B, typename T, std::size_t I, std::size_t D>
 
128
struct indexed_access<box_tag, B, T, I, D>
 
129
{
 
130
    static inline T get(const B& b)
 
131
    {
 
132
        return traits::indexed_access<B, I, D>::get(b);
 
133
    }
 
134
    static inline void set(B& b, const T& value)
 
135
    {
 
136
        traits::indexed_access<B, I, D>::set(b, value);
 
137
    }
 
138
};
 
139
 
 
140
template <typename S, typename T, std::size_t I, std::size_t D>
 
141
struct indexed_access<segment_tag, S, T, I, D>
 
142
{
 
143
    static inline T get(const S& segment)
 
144
    {
 
145
        return traits::indexed_access<S, I, D>::get(segment);
 
146
    }
 
147
    static inline void set(S& segment, const T& value)
 
148
    {
 
149
        traits::indexed_access<S, I, D>::set(segment, value);
 
150
    }
 
151
};
 
152
 
 
153
} // namespace core_dispatch
 
154
#endif // DOXYGEN_NO_DISPATCH
 
155
 
 
156
 
 
157
#ifndef DOXYGEN_NO_DETAIL
 
158
namespace detail
 
159
{
 
160
 
 
161
// Two dummy tags to distinguish get/set variants below.
 
162
// They don't have to be specified by the user. The functions are distinguished
 
163
// by template signature also, but for e.g. GCC this is not enough. So give them
 
164
// a different signature.
 
165
struct signature_getset_dimension {};
 
166
struct signature_getset_index_dimension {};
 
167
 
 
168
} // namespace detail
 
169
#endif // DOXYGEN_NO_DETAIL
 
170
 
 
171
 
 
172
/*!
 
173
    \brief get a coordinate value of a point / nsphere
 
174
    \return coordinate value
 
175
    \ingroup access
 
176
    \tparam D dimension
 
177
    \tparam G geometry
 
178
    \param geometry geometry to get coordinate value from
 
179
    \param dummy does not have to be specified
 
180
*/
 
181
template <std::size_t D, typename G>
 
182
inline typename coordinate_type<G>::type get(const G& geometry,
 
183
    detail::signature_getset_dimension* dummy = 0)
 
184
{
 
185
    boost::ignore_unused_variable_warning(dummy);
 
186
 
 
187
    typedef typename boost::remove_const<G>::type ncg_type;
 
188
 
 
189
    typedef core_dispatch::access
 
190
        <
 
191
        typename tag<G>::type,
 
192
        ncg_type,
 
193
        typename coordinate_type<ncg_type>::type,
 
194
        D
 
195
        > coord_access_type;
 
196
 
 
197
    return coord_access_type::get(geometry);
 
198
}
 
199
 
 
200
 
 
201
/*!
 
202
    \brief assign coordinate value to a point / sphere
 
203
    \ingroup access
 
204
    \tparam D dimension
 
205
    \tparam G geometry
 
206
    \param geometry geometry to assign coordinate to
 
207
    \param value coordinate value to assign
 
208
    \param dummy does not have to be specified
 
209
*/
 
210
template <std::size_t D, typename G>
 
211
inline void set(G& geometry, const typename coordinate_type<G>::type& value,
 
212
    detail::signature_getset_dimension* dummy = 0)
 
213
{
 
214
    boost::ignore_unused_variable_warning(dummy);
 
215
    
 
216
        typedef typename boost::remove_const<G>::type ncg_type;
 
217
 
 
218
    typedef core_dispatch::access
 
219
        <
 
220
        typename tag<G>::type,
 
221
        ncg_type,
 
222
        typename coordinate_type<ncg_type>::type,
 
223
        D
 
224
        > coord_access_type;
 
225
 
 
226
    coord_access_type::set(geometry, value);
 
227
}
 
228
 
 
229
// Note: doxygen needs a construct to distinguish get/set (like the gcc compiler)
 
230
 
 
231
/*!
 
232
    \brief get a coordinate value of a box / segment
 
233
    \return coordinate value
 
234
    \ingroup access
 
235
    \tparam I index, for boxes: min_corner or max_corner. For segment: 0 / 1
 
236
    \tparam D dimension
 
237
    \tparam G geometry
 
238
    \param geometry geometry to get coordinate value from
 
239
    \param dummy does not have to be specified
 
240
*/
 
241
template <std::size_t I, std::size_t D, typename G>
 
242
inline typename coordinate_type<G>::type get(const G& geometry,
 
243
    detail::signature_getset_index_dimension* dummy = 0)
 
244
{
 
245
    boost::ignore_unused_variable_warning(dummy);
 
246
    
 
247
    typedef typename boost::remove_const<G>::type ncg_type;
 
248
 
 
249
    typedef core_dispatch::indexed_access
 
250
        <
 
251
        typename tag<G>::type,
 
252
        ncg_type,
 
253
        typename coordinate_type<ncg_type>::type,
 
254
        I,
 
255
        D
 
256
        > coord_access_type;
 
257
 
 
258
    return coord_access_type::get(geometry);
 
259
}
 
260
 
 
261
/*!
 
262
    \brief assign a coordinate value of a box / segment
 
263
    \ingroup access
 
264
    \tparam I index, for boxes: min_corner or max_corner. For segment: 0 / 1
 
265
    \tparam D dimension
 
266
    \tparam G geometry
 
267
    \param geometry geometry to assign coordinate to
 
268
    \param value coordinate value to assign
 
269
    \param dummy does not have to be specified
 
270
*/
 
271
template <std::size_t I, std::size_t D, typename G>
 
272
inline void set(G& geometry, const typename coordinate_type<G>::type& value,
 
273
    detail::signature_getset_index_dimension* dummy = 0)
 
274
{
 
275
    boost::ignore_unused_variable_warning(dummy);
 
276
    
 
277
    typedef typename boost::remove_const<G>::type ncg_type;
 
278
 
 
279
    typedef core_dispatch::indexed_access
 
280
        <
 
281
        typename tag<G>::type, ncg_type,
 
282
        typename coordinate_type<ncg_type>::type,
 
283
        I,
 
284
        D
 
285
        > coord_access_type;
 
286
 
 
287
    coord_access_type::set(geometry, value);
 
288
}
 
289
 
 
290
} // namespace ggl
 
291
 
 
292
#endif // GGL_CORE_ACCESS_HPP