1
#ifndef _RHEOLEF_VEC_CONCAT_H
2
#define _RHEOLEF_VEC_CONCAT_H
4
/// This file is part of Rheolef.
6
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
8
/// Rheolef is free software; you can redistribute it and/or modify
9
/// it under the terms of the GNU General Public License as published by
10
/// the Free Software Foundation; either version 2 of the License, or
11
/// (at your option) any later version.
13
/// Rheolef is distributed in the hope that it will be useful,
14
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
/// GNU General Public License for more details.
18
/// You should have received a copy of the GNU General Public License
19
/// along with Rheolef; if not, write to the Free Software
20
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
/// =========================================================================
23
// build vec from initializer lists
25
#include "rheolef/vec.h"
29
template <class T, class M>
30
struct vec_concat_value {
32
typedef enum { scalar, vector} variant_type;
34
vec_concat_value (const T& x) : s(x), v(), variant(scalar) {}
35
vec_concat_value (const vec<T,M>& x) : s(), v(x), variant(vector) {}
37
friend std::ostream& operator<< (std::ostream& o, const vec_concat_value<T,M>& x) {
38
if (x.variant == scalar) return o << "s"; else return o << "v";
47
template <class T, class M>
50
typedef typename vec<T,M>::size_type size_type;
51
typedef vec_concat_value<T,M> value_type;
55
vec_concat () : _l() {}
58
vec_concat (const std::initializer_list<vec<T,M> >& il) : _l() {
59
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
60
typedef typename std::initializer_list<vec<T,M> >::const_iterator const_iterator;
61
#else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
62
typedef const vec<T,M>* const_iterator;
63
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
64
for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
65
_l.push_back(value_type(*iter));
70
vec_concat (const std::initializer_list<value_type>& il) : _l() {
71
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
72
typedef typename std::initializer_list<value_type>::const_iterator const_iterator;
73
#else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
74
typedef const value_type* const_iterator;
75
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
76
for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
80
friend std::ostream& operator<< (std::ostream& o, const vec_concat<T,M>& x) {
82
for(typename std::list<value_type>::const_iterator iter = x._l.begin(); iter != x._l.end(); ++iter) {
83
std::cout << *iter << " ";
85
return std::cout << "}";
87
vec<T,M> build_vec() const;
90
std::list<value_type> _l;
92
template <class T, class M>
94
vec_concat<T,M>::build_vec() const
96
// ------------------------------------
97
// first pass: compute the vector size
98
// ------------------------------------
101
size_type v_dis_sz = 0;
103
for(typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
104
const vec_concat_value<T,M>& x = *iter;
105
if (x.variant == value_type::vector) {
106
comm = x.v.ownership().comm();
107
v_sz += x.v.ownership().size();
108
v_dis_sz += x.v.ownership().dis_size();
114
if (comm.rank() == comm.size() - 1) { v_sz += s_sz; }
115
distributor ownership (v_dis_sz, comm, v_sz);
116
// ------------------------
117
// second pass: copy values
118
// ------------------------
119
vec<T,M> u (ownership);
120
size_type my_proc = comm.rank();
121
size_type last_proc = comm.size() - 1;
122
typename vec<T,M>::iterator pu = u.begin();
123
for(typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
124
const vec_concat_value<T,M>& x = *iter;
125
if (x.variant == value_type::vector) {
126
for (typename vec<T,M>::const_iterator pv = x.v.begin(), lastv = x.v.end(); pv != lastv; pv++) {
130
if (my_proc == last_proc) {
137
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
138
template <class T, class M>
140
vec<T,M>::vec (const std::initializer_list<vec_concat_value<T,M> >& init_list)
142
vec_concat<T,M> vc (init_list);
143
vec<T,M>::operator= (vc.build_vec());
145
template <class T, class M>
148
vec<T,M>::operator= (const std::initializer_list<vec_concat_value<T,M> >& init_list)
150
vec_concat<T,M> vc (init_list);
151
vec<T,M>::operator= (vc.build_vec());
154
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
156
} // namespace rheolef
157
#endif // _RHEOLEF_VEC_CONCAT_H