Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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"
32namespace rheolef {
33
34// there is a non-standard SGI extension like that:
35template <class T1, class T2>
36struct select1st : std::unary_function<std::pair<T1,T2>, T1> {
37 T1 operator() (const std::pair<T1,T2>& x) const { return x.first; }
38};
39template <class T1, class T2>
40struct 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
45template <class T>
46struct always_true : std::unary_function<T,bool> {
47 bool operator()(const T& x) const { return true; }
48};
49// index iterator, simulates array[i] = i
50template <class Size, class Distance = std::ptrdiff_t>
51class index_iterator : public std::iterator<std::input_iterator_tag, Size, Distance, const Size*, const Size&> {
52public:
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) {}
66protected:
67 Size _i;
68};
69
70// f1(pair x) = x.first
71template <class Pair>
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
79template <class Pair>
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:
88template<class Pair1, class Pair2>
89struct 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
94template <class Iterator, class Operator>
95class apply_iterator : public std::iterator_traits<Iterator> {
96public:
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); }
107protected:
108 Iterator i;
109 Operator op;
110};
111template <class Iterator, class Operator>
112inline
114make_apply_iterator(Iterator i, Operator op) {
116}
117// some c++ cannot convert pair<const I,T> to pair<I,T>:
118template <class InputIterator, class OutputIterator>
119OutputIterator
120msg_pair_copy(InputIterator input, InputIterator last,
121OutputIterator 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
134namespace rheolef { namespace details {
135
136// concept of class_reference
137// such as disarray::dis_reference
138template<class T>
139struct 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) \
150struct 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
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) \
204struct 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:
218template <class T>
219struct 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
232namespace rheolef { namespace details {
233
234template<class T>
235struct is_container : std::false_type {
236 typedef std::false_type type;
237};
238#ifdef _RHEOLEF_HAVE_MPI
239template <class T>
240struct 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
apply_iterator & operator++()
Definition msg_util.h:100
bool operator!=(apply_iterator< Iterator, Operator > b) const
Definition msg_util.h:106
apply_iterator(Iterator i1, Operator op1)
Definition msg_util.h:98
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
index_iterator & operator++()
Definition msg_util.h:53
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
const Size & operator[](const Size &i) const
Definition msg_util.h:60
index_iterator operator++(int)
Definition msg_util.h:54
Expr1::float_type T
Definition field_expr.h:230
#define _RHEOLEF_generic_set_xxx_op(NAME, OP)
Definition msg_util.h:149
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, typenamePair::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, typenamePair::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