~ubuntu-branches/ubuntu/trusty/rheolef/trusty

« back to all changes in this revision

Viewing changes to skit/plib2/polymorphic_data_map.h

  • Committer: Package Import Robot
  • Author(s): Pierre Saramito
  • Date: 2012-04-06 09:12:21 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120406091221-m58me99p1nxqui49
Tags: 6.0-1
* New upstream release 6.0 (major changes):
  - massively distributed and parallel support
  - full FEM characteristic method (Lagrange-Gakerkin method) support
  - enhanced users documentation 
  - source code supports g++-4.7 (closes: #667356)
* debian/control: dependencies for MPI distributed solvers added
* debian/rules: build commands simplified
* debian/librheolef-dev.install: man1/* to man9/* added
* debian/changelog: package description rewritted (closes: #661689)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifndef BOOST_PP_IS_ITERATING
2
 
#ifndef _RHEOLEF_POLYMORPHIC_DATA_MAP_H
3
 
#define _RHEOLEF_POLYMORPHIC_DATA_MAP_H
4
 
///
5
 
/// This file is part of Rheolef.
6
 
///
7
 
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
8
 
///
9
 
/// Rheolef is free software; you can redistribute it and/or modify
10
 
/// it under the terms of the GNU General Public License as published by
11
 
/// the Free Software Foundation; either version 2 of the License, or
12
 
/// (at your option) any later version.
13
 
///
14
 
/// Rheolef is distributed in the hope that it will be useful,
15
 
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
/// GNU General Public License for more details.
18
 
///
19
 
/// You should have received a copy of the GNU General Public License
20
 
/// along with Rheolef; if not, write to the Free Software
21
 
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 
///
23
 
/// =========================================================================
24
 
 
25
 
#include "rheolef/polymorphic_data_vector.h"
26
 
 
27
 
#include <map>
28
 
#include <typeinfo>
29
 
#include <boost/array.hpp>
30
 
#include <boost/mpl/vector.hpp>
31
 
#include <boost/mpl/size.hpp>
32
 
#include <boost/mpl/for_each.hpp>
33
 
#include <boost/mpl/at.hpp>
34
 
 
35
 
namespace rheolef {
36
 
namespace mpl = boost::mpl;
37
 
 
38
 
// -----------------------------------------------------------------------
39
 
// some auxilliary functions
40
 
// -----------------------------------------------------------------------
41
 
/// @brief transform a map::iterator into a void*
42
 
template <class MapTk>
43
 
void*
44
 
to_pointer (typename MapTk::iterator iter_tk)
45
 
{
46
 
  return static_cast<void*>(iter_tk._M_node); // WARNING: depend upon GNU C++ STL (HP & SGI)
47
 
}
48
 
/// @brief transform a void* into a map::iterator
49
 
template <class MapTk>
50
 
typename MapTk::iterator
51
 
to_iterator (void* ptr)
52
 
{
53
 
  typedef typename MapTk::iterator iterator;
54
 
  typedef typename iterator::_Link_type link_type;
55
 
  return iterator (static_cast<link_type>(ptr));
56
 
}
57
 
// -----------------------------------------------------------------------
58
 
// Advantage of this class: allows replacement of a i-th element in the table
59
 
//   by another that could have a different derived type.
60
 
//   possible application: replace a triangle by a curvilinear triangle
61
 
//   on the boundary. Suitable for P2 boundary transformation.
62
 
//
63
 
/// @brief dynamic memory area handler for polymorphic_array
64
 
template <class T, class V, int NV>
65
 
struct polymorphic_data_map {};
66
 
 
67
 
// --------------------------------------------------------------------------------
68
 
// new_entry<Tk>() returns a pointer Tk* newly allocated into the data structure
69
 
// via a push_back. We need a specialisation of a template member function
70
 
// into a template class. This is not allowed... So, we use the same trick as 
71
 
// for the "reserve(n)" member: we use a template class-function, with specialisation.
72
 
//
73
 
template <class Tk, class T, class V, int NV>
74
 
struct my_new_entry_map_t {
75
 
  Tk* operator() (polymorphic_data_map<T,V,NV>& x) {
76
 
    error_macro ("unexpected type " << typename_macro(Tk));
77
 
    return 0;
78
 
  }
79
 
};
80
 
// ----------------------------------------------------------
81
 
// run here the recursive inclusion of this file:
82
 
// ----------------------------------------------------------
83
 
// _RHEOLEF_POLYMORPHIC_MAX_SIZE was defined by "polymorphic_data_vector.h"
84
 
#define BOOST_PP_ITERATION_LIMITS (0, _RHEOLEF_POLYMORPHIC_MAX_SIZE)
85
 
#define BOOST_PP_FILENAME_1    "rheolef/polymorphic_data_map.h" // this file
86
 
#include BOOST_PP_ITERATE()
87
 
 
88
 
} // namespace rheolef
89
 
#endif // _RHEOLEF_POLYMORPHIC_DATA_MAP_H
90
 
#else  // BOOST_PP_IS_ITERATING
91
 
// ----------------------------------------------------------
92
 
// here, this file is recursively included with growing "N" :
93
 
// ----------------------------------------------------------
94
 
#define N    BOOST_PP_ITERATION()
95
 
 
96
 
template <class T, class V>
97
 
struct polymorphic_data_map<T,V,N> {
98
 
 
99
 
// typedefs:
100
 
 
101
 
    static const size_t _n_variant  = mpl::size<V>::value; // should be = N
102
 
    typedef typename std::vector<int>::size_type size_type;
103
 
 
104
 
#define _RHEOLEF_typedef(z,k,unused)                                    \
105
 
    typedef typename mpl::at_c<V,k>::type T##k;                         \
106
 
    typedef std::map <size_type, T##k, std::less<size_type>,            \
107
 
        heap_allocator<std::pair<size_type, T##k> > >  map##k##_type;
108
 
    BOOST_PP_REPEAT(N, _RHEOLEF_typedef, ~)
109
 
#undef _RHEOLEF_typedef
110
 
 
111
 
// cstors :
112
 
 
113
 
#define _RHEOLEF_stack_initializer(z,k,unused)                          \
114
 
        _stack_##k(), 
115
 
 
116
 
    polymorphic_data_map(size_type n=0) :
117
 
        BOOST_PP_REPEAT(N, _RHEOLEF_stack_initializer, ~)
118
 
        _counter(),
119
 
        _size(0),
120
 
        _max_size(n)
121
 
    {
122
 
        std::fill (_counter.begin(), _counter.end(), 0);
123
 
    }
124
 
    void resize (size_type n) {
125
 
        _max_size = n;
126
 
    }
127
 
 
128
 
#undef _RHEOLEF_stack_initializer
129
 
 
130
 
// accessors & modifiers:
131
 
 
132
 
 
133
 
    size_type size () const { return _max_size; }
134
 
    size_type size (size_type k)    const { return _counter[k]; }
135
 
    const size_type* begin_sizes () const { return _counter.begin(); }
136
 
 
137
 
    void erase (size_type index);
138
 
 
139
 
#define _RHEOLEF_assign(z,k,unused)                                                     \
140
 
    void assign (size_type index, const T##k& value);
141
 
    BOOST_PP_REPEAT(N, _RHEOLEF_assign, ~)
142
 
#undef _RHEOLEF_assign
143
 
 
144
 
    void reset () {
145
 
 
146
 
#define _RHEOLEF_stack_clear(z,k,unused)                        \
147
 
        _stack_##k.clear();
148
 
        BOOST_PP_REPEAT(N, _RHEOLEF_stack_clear, ~)
149
 
#undef _RHEOLEF_stack_clear
150
 
 
151
 
        std::fill (_counter.begin(), _counter.end(), 0);
152
 
        _size = 0;
153
 
    }
154
 
    void update_sizes () { 
155
 
 
156
 
#define _RHEOLEF_stack_set_counter(z,k,unused)                  \
157
 
        _counter[k] = _stack_##k.size();
158
 
        BOOST_PP_REPEAT(N, _RHEOLEF_stack_set_counter, ~)
159
 
#undef _RHEOLEF_stack_set_counter
160
 
 
161
 
        _size = 0;
162
 
        for (size_type k = 0; k < _n_variant; k++) {
163
 
          _size += _counter[k];
164
 
        }
165
 
    }
166
 
 
167
 
    template <class Tk> Tk* new_entry ();
168
 
 
169
 
// data:
170
 
 
171
 
#define _RHEOLEF_stack_declare(z,k,unused)                      \
172
 
    map##k##_type                               _stack_##k;
173
 
    BOOST_PP_REPEAT(N, _RHEOLEF_stack_declare, ~)
174
 
#undef _RHEOLEF_stack_declare
175
 
 
176
 
    boost::array<size_type,_n_variant>        _counter;
177
 
    size_type                                 _size;
178
 
    size_type                                 _max_size;
179
 
 
180
 
};
181
 
// asignment: x[i] = value
182
 
// it's more complex: if value is of type Tk, and x[i] points to a Tl != Tk
183
 
// then, we have to clear the old x[i] object from the l-eme map structure,
184
 
// en ayant avant sauvegarde' son index (qui doit etre egal a i..)
185
 
// et inserer valeur dans la Tk-stack avec cet index
186
 
template <class T, class V>
187
 
void
188
 
polymorphic_data_map<T,V,N>::erase (size_type global_index) {
189
 
#define _RHEOLEF_erase(z,k,unused)                                                      \
190
 
    typename map##k##_type::iterator iter_##k = _stack_##k.find(global_index);          \
191
 
    if (iter_##k != _stack_##k.end()) {                                                 \
192
 
        _stack_##k.erase (iter_##k);                                                    \
193
 
        _counter[k]--;                                                                  \
194
 
        _size--;                                                                        \
195
 
    }
196
 
    BOOST_PP_REPEAT(N, _RHEOLEF_erase, ~)
197
 
#undef _RHEOLEF_erase
198
 
}
199
 
 
200
 
#define _RHEOLEF_assign(z,k,unused)                                                     \
201
 
template <class T, class V>                                                             \
202
 
void                                                                                    \
203
 
polymorphic_data_map<T,V,N>::assign (size_type global_index, const T##k& value) {       \
204
 
    /* erase any value with the same index */                                           \
205
 
    erase (global_index);                                                               \
206
 
    /* here, the location is empty: insert */                                           \
207
 
    typedef typename map##k##_type::iterator iterator;                                  \
208
 
    std::pair<iterator,bool> status                                                     \
209
 
         = _stack_##k.insert (std::pair<size_type,T##k>(global_index,value));           \
210
 
    check_macro (status.second, "insert failed");                                       \
211
 
    _counter[k]++;                                                                      \
212
 
    _size++;                                                                            \
213
 
}
214
 
BOOST_PP_REPEAT(N, _RHEOLEF_assign, ~)
215
 
#undef _RHEOLEF_assign
216
 
 
217
 
// convert a data_map into a data(vector)
218
 
template <class T, class V>
219
 
void
220
 
polymorphic_data_vector<T,V,N>::build (const class polymorphic_data_map<T,V,N>& pool)
221
 
{
222
 
#define _RHEOLEF_stack_copy(z,k,unused)                                         \
223
 
    _stack_##k.resize (pool._stack_##k.size());                                 \
224
 
    copy (pool._stack_##k.begin(), pool._stack_##k.end(), _stack_##k.begin());
225
 
 
226
 
    BOOST_PP_REPEAT(N, _RHEOLEF_stack_copy, ~)
227
 
    std::copy (pool._counter.begin(), pool._counter.end(), _counter.begin());
228
 
    _size = pool._size;
229
 
 
230
 
#undef _RHEOLEF_stack_copy
231
 
}
232
 
// specialization for each Tk:
233
 
#define _RHEOLEF_new_entry(z,k,unused)                                          \
234
 
template <class T, class V>                                                     \
235
 
struct my_new_entry_map_t <typename polymorphic_data_map<T,V,N>::T##k, T,V,N> { \
236
 
  typedef typename polymorphic_data_map<T,V,N>::T##k T##k;                      \
237
 
  typedef typename polymorphic_data_map<T,V,N>::size_type size_type;            \
238
 
  T##k* operator()  (polymorphic_data_map<T,V,N>& x) {                          \
239
 
        typedef typename polymorphic_data_map<T,V,N>::map##k##_type map_type;   \
240
 
        typedef typename map_type::iterator                  iterator;          \
241
 
        check_macro (x._size < x._max_size, "too many entries");                \
242
 
        const size_type variant = k;                                            \
243
 
        std::pair<iterator,bool> status                                         \
244
 
         = x._stack_##k.insert (std::pair<size_type,T##k> (x._size, T##k()));   \
245
 
        check_macro (status.second, "insert failed");                           \
246
 
        iterator iter = status.first;                                           \
247
 
        x._counter[variant]++;                                                  \
248
 
        x._size++;                                                              \
249
 
        T##k* p = &((*iter).second);                                            \
250
 
        return p;                                                               \
251
 
  }                                                                             \
252
 
};
253
 
BOOST_PP_REPEAT(N, _RHEOLEF_new_entry, ~)
254
 
#undef _RHEOLEF_new_entry
255
 
 
256
 
template <class T, class V>
257
 
template <class Tk>
258
 
inline
259
 
Tk*
260
 
polymorphic_data_map<T,V,N>::new_entry ()
261
 
{
262
 
  my_new_entry_map_t<Tk,T,V,N> new_entry_f;
263
 
  return new_entry_f (*this);
264
 
}
265
 
 
266
 
#endif // BOOST_PP_IS_ITERATING