Rheolef  7.2
an efficient C++ finite element environment
msg_util.h
Go to the documentation of this file.
1 #ifndef _RHEO_MSG_UTIL_H
2 #define _RHEO_MSG_UTIL_H
23 //
24 // utilities for message exchange basic algorithms
25 // implemented with MPI
26 //
27 // author: Pierre.Saramito@imag.fr
28 //
29 // date: 17 december 1998
30 //
31 # include "rheolef/communicator.h"
32 namespace rheolef {
33 
34 // there is a non-standard SGI extension like that:
35 template <class T1, class T2>
36 struct select1st : std::unary_function<std::pair<T1,T2>, T1> {
37  T1 operator() (const std::pair<T1,T2>& x) const { return x.first; }
38 };
39 template <class T1, class T2>
40 struct select2nd : std::unary_function<std::pair<T1,T2>, T2> {
41  T2 operator() (const std::pair<T1,T2>& x) const { return x.second; }
42 };
43 
44 // always true predicate
45 template <class T>
46 struct always_true : std::unary_function<T,bool> {
47  bool operator()(const T& x) const { return true; }
48 };
49 // index iterator, simulates array[i] = i
50 template <class Size, class Distance = std::ptrdiff_t>
51 class index_iterator : public std::iterator<std::input_iterator_tag, Size, Distance, const Size*, const Size&> {
52 public:
53  index_iterator& operator++() { _i++; return *this; }
56  _i++;
57  return tmp;
58  }
59  const Size& operator*() const { return _i; }
60  const Size& operator[](const Size& i) const { return i; }
62  return x._i == _i; }
64  return !(x._i == _i); }
65  index_iterator(Size i0 = 0) : _i(i0) {}
66 protected:
67  Size _i;
68 };
69 
70 // f1(pair x) = x.first
71 template <class Pair>
72 struct first_op
73 : public std::unary_function<Pair,typename Pair::first_type> {
74  typename std::unary_function<Pair,typename Pair::first_type>::result_type
75  operator()(const Pair& x) const {
76  return x.first; }
77 };
78 // f2(pair x) = x.second
79 template <class Pair>
80 struct second_op
81  : public std::unary_function<Pair, typename Pair::second_type> {
82  typename std::unary_function<Pair,typename Pair::second_type>::result_type
83  operator()(const Pair& x) const {
84  return x.second; }
85 };
86 // pair<const uint, T> and pair<uint, T> are not compatible
87 // for some C++; so convert it explicitly:
88 template<class Pair1, class Pair2>
89 struct pair_identity : public std::unary_function<Pair1, Pair2> {
90  Pair2 operator()(const Pair1& x) const {
91  return Pair2(x.first, x.second); }
92 };
93 // wrapper iterator class that applies an operator
94 template <class Iterator, class Operator>
95 class apply_iterator : public std::iterator_traits<Iterator> {
96 public:
97  typedef typename Operator::result_type value_type;
98  apply_iterator(Iterator i1, Operator op1)
99  : i(i1), op(op1) {}
101  i++; return *this; }
103  apply_iterator t = *this; i++; return t; }
104  value_type operator*() const { return op(*i); }
105  bool operator== (apply_iterator<Iterator,Operator> b) const{ return (i == b.i); }
106  bool operator!= (apply_iterator<Iterator,Operator> b) const{ return (i != b.i); }
107 protected:
108  Iterator i;
109  Operator op;
110 };
111 template <class Iterator, class Operator>
112 inline
114 make_apply_iterator(Iterator i, Operator op) {
115  return apply_iterator<Iterator,Operator>(i,op);
116 }
117 // some c++ cannot convert pair<const I,T> to pair<I,T>:
118 template <class InputIterator, class OutputIterator>
119 OutputIterator
120 msg_pair_copy(InputIterator input, InputIterator last,
121 OutputIterator result) {
122  while (input != last) {
123  (*result).first = (*input).first;
124  (*result++).second = (*input++).second;
125  }
126  return result;
127 }
128 } // namespace rheolef
129 // ----------------------------------------------------------------------------
130 // generic set_op for the operator= += -= definition
131 // ----------------------------------------------------------------------------
132 // author: Pierre.Saramito@imag.fr
133 // date: 13 april 2020
134 namespace rheolef { namespace details {
135 
136 // concept of class_reference
137 // such as disarray::dis_reference
138 template<class T>
139 struct is_class_reference : std::false_type {};
140 
141 // generic "set_op" used to define
142 // operator= += -=
143 // should work at least when
144 // - T1=T2=double
145 // - Reference=disarray::dis_reference and T=double
146 // - IndexSet=index_set and T=int or size_t
147 // - PairSet=index_set and T=double and Size=size_t
148 //
149 #define _RHEOLEF_generic_set_xxx_op(NAME,OP) \
150 struct NAME { \
151  template <class T1, class T2> \
152  typename std::enable_if< \
153  std::is_convertible<T1,T2>::value \
154  ,T2&>::type \
155  operator() (T2& x, const T1& y) const { x OP y; return x; } \
156  \
157  template <class T, class Reference> \
158  typename std::enable_if< \
159  !std::is_convertible<T,Reference>::value && \
160  is_class_reference<Reference>::value && \
161  std::is_member_function_pointer< \
162  decltype(static_cast<Reference& (Reference::*)(T)> \
163  (&Reference::operator OP)) \
164  >::value \
165  ,Reference>::type \
166  operator() (Reference x, const T& y) const { x OP y; return x; } \
167  \
168  template <class T, class Reference> \
169  typename std::enable_if< \
170  !std::is_convertible<T,Reference>::value && \
171  std::is_class<Reference>::value && \
172  std::is_member_function_pointer< \
173  decltype(static_cast<Reference& (Reference::*)(const T&)> \
174  (&Reference::operator OP)) \
175  >::value \
176  ,Reference>::type \
177  operator() (Reference x, const T& y) const { x OP y; return x; } \
178  \
179  template <class T, class IndexSet> \
180  typename std::enable_if< \
181  std::is_convertible<T,size_t>::value && \
182  std::is_class<IndexSet>::value && \
183  std::is_member_function_pointer< \
184  decltype(static_cast<IndexSet& (IndexSet::*)(size_t)> \
185  (&IndexSet::operator OP)) \
186  >::value \
187  ,IndexSet&>::type \
188  operator() (IndexSet& x, const T& y) const { x OP y; return x; } \
189  \
190  template <class T, class PairSet, class Size> \
191  typename std::enable_if< \
192  std::is_convertible<Size,size_t>::value && \
193  std::is_class<PairSet>::value \
194  ,PairSet&>::type \
195  operator() (PairSet& x, const std::pair<Size,T>& y) const { x OP y; return x; } \
196 };
197 
198  _RHEOLEF_generic_set_xxx_op(generic_set_op,=)
199  _RHEOLEF_generic_set_xxx_op(generic_set_plus_op,+=)
200  _RHEOLEF_generic_set_xxx_op(generic_set_minus_op,-=)
201 #undef _RHEOLEF_generic_set_xxx_op
202 
203 #define _RHEOLEF_generic_set_xxx_op(NAME,FUN) \
204 struct NAME { \
205  template <class T1, class T2> \
206  typename std::enable_if< \
207  std::is_convertible<T1,T2>::value \
208  ,T2&>::type \
209  operator() (T2& x, const T1& y) const { return x = FUN(x,T2(y)); } \
210 };
211 
212  _RHEOLEF_generic_set_xxx_op(generic_set_min_op,std::min)
213  _RHEOLEF_generic_set_xxx_op(generic_set_max_op,std::max)
214 #undef _RHEOLEF_generic_set_xxx_op
215 
216 // this traits will be overloaded by index_set and pair_set
217 // as generic_set_plus_op:
218 template <class T>
219 struct default_set_op_traits {
220  using type = generic_set_op;
221 };
222 
223 }} // namespace rheolef::details
224 // ----------------------------------------------------------------------------
225 // container traits
226 // ----------------------------------------------------------------------------
227 #include <boost/serialization/utility.hpp>
228 #ifdef _RHEOLEF_HAVE_MPI
229 #include <boost/mpi/datatype.hpp>
230 #endif // _RHEOLEF_HAVE_MPI
231 
232 namespace rheolef { namespace details {
233 
234 template<class T>
235 struct is_container : std::false_type {
236  typedef std::false_type type;
237 };
238 #ifdef _RHEOLEF_HAVE_MPI
239 template <class T>
240 struct is_container_of_mpi_datatype : std::false_type {
241  typedef std::false_type type;
242 };
243 #endif // _RHEOLEF_HAVE_MPI
244 }} // namespace rheolef::details
245 #endif // _RHEO_MSG_UTIL_H
bool operator==(apply_iterator< Iterator, Operator > b) const
Definition: msg_util.h:105
bool operator!=(apply_iterator< Iterator, Operator > b) const
Definition: msg_util.h:106
apply_iterator(Iterator i1, Operator op1)
Definition: msg_util.h:98
apply_iterator & operator++()
Definition: msg_util.h:100
value_type operator*() const
Definition: msg_util.h:104
apply_iterator operator++(int)
Definition: msg_util.h:102
Operator::result_type value_type
Definition: msg_util.h:97
const Size & operator[](const Size &i) const
Definition: msg_util.h:60
bool operator!=(const index_iterator< Size, Distance > &x) const
Definition: msg_util.h:63
const Size & operator*() const
Definition: msg_util.h:59
bool operator==(const index_iterator< Size, Distance > &x) const
Definition: msg_util.h:61
index_iterator(Size i0=0)
Definition: msg_util.h:65
index_iterator operator++(int)
Definition: msg_util.h:54
index_iterator & operator++()
Definition: msg_util.h:53
rheolef::space_base_rep< T, M > t
rheolef::std type
Expr1::float_type T
Definition: field_expr.h:230
_RHEOLEF_generic_set_xxx_op(generic_set_op,=) _RHEOLEF_generic_set_xxx_op(generic_set_plus_op
This file is part of Rheolef.
OutputIterator msg_pair_copy(InputIterator input, InputIterator last, OutputIterator result)
Definition: msg_util.h:120
apply_iterator< Iterator, Operator > make_apply_iterator(Iterator i, Operator op)
Definition: msg_util.h:114
bool operator()(const T &x) const
Definition: msg_util.h:47
std::unary_function< Pair, typename Pair::first_type >::result_type operator()(const Pair &x) const
Definition: msg_util.h:75
Pair2 operator()(const Pair1 &x) const
Definition: msg_util.h:90
std::unary_function< Pair, typename Pair::second_type >::result_type operator()(const Pair &x) const
Definition: msg_util.h:83
T1 operator()(const std::pair< T1, T2 > &x) const
Definition: msg_util.h:37
T2 operator()(const std::pair< T1, T2 > &x) const
Definition: msg_util.h:41