This file is indexed.

/usr/include/rheolef/compose.h is in librheolef-dev 6.6-1build2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
#ifndef _RHEOLEF_COMPOSE_H
#define _RHEOLEF_COMPOSE_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito 
//
// Rheolef is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// Rheolef is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// ==========================================================================
// 
// compose a n-ary function with n fields : compose(f,uh1...uhN)
//
// author: Pierre.Saramito@imag.fr
//
// date: 4 september 2015
//
//<compose:  
/*Class:compose
NAME:  @code{compose} - a n-ary function with n fields
DESCRIPTION:       
  @noindent
  Compose a n-ary function f with n fields.
  @example
        geo omega ("circle");
        space Xh (omega, "P1");
        field uh (Xh, 1.0);
        field vh = interpolate (compose(f,uh));
  @end example
  The @code{compose} operator could be used in all non-linear expressions
  involved in either the @code{interpolate} or the @code{integrate} functions
  (see @ref{interpolate algorithm} and @ref{integrate algorithm}).
  The @code{f} function could be either a usual function or a functor.
CHARACTERISTIC:
  The @code{compose} function supports also the characteristic algorithm
  (see @ref{characteristic class})
  used for convection.
  @example
        characteristic X (-delta_t*uh);
        test v (Xh);
        field lh = integrate (compose(uh,X)*v);
  @end example
IMPLEMENTATION:
  The n-arity bases on the variadic template feature of the 2011 c++ normalisation.
  When this feature is not available, only unary and binary functions are supported.
AUTHOR: Pierre.Saramito@imag.fr
DATE:   3 september 2015
End:
*/
#include "rheolef/promote.h"
#include "rheolef/field_expr.h"

#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/function_arity.hpp>

namespace rheolef {

// ------------------------------------------
// tools for creating index lists (TODO: move in utilities)
// ------------------------------------------
// TODO: C++2014 introduced index_sequence : test configure, etc
namespace details {

// the structure that encapsulates index lists
template <size_t... Is>
struct index_list {};

// Collects internal details for generating index ranges [MIN, MAX)
    // declare primary template for index range builder
    template <size_t MIN, size_t N, size_t... Is>
    struct range_builder;

    // base step
    template <size_t MIN, size_t... Is>
    struct range_builder<MIN, MIN, Is...>
    {
        typedef index_list<Is...> type;
    };

    // induction step
    template <size_t MIN, size_t N, size_t... Is>
    struct range_builder: public range_builder<MIN, N - 1, N - 1, Is...>
    {
    };

// Meta-function that returns a [MIN, MAX[ index range
template<size_t MIN, size_t MAX>
using index_range = typename range_builder<MIN, MAX>::type;

} // namespace details
// ---------------------------------------------------------------------------
// functor traits (TODO: move in utilities)
// ---------------------------------------------------------------------------
namespace details {

template <typename T>
struct functor_traits : public functor_traits<decltype(&T::operator())> {};

template <typename C, typename Ret, typename... Args>
struct functor_traits<Ret(C::*)(Args...) const> {
    using result_type =  Ret;
    template <std::size_t i>
    struct arg {
        using type = typename std::tuple_element<i, std::tuple<Args...> >::type;
        using decay_type = typename std::decay<type>::type;
    };
};

template <typename T1, typename T2>
struct decay_is_equivalent
  : std::is_same<
	typename std::decay<T1>::type, 
	typename std::decay<T2>::type
    >::type 
{};


} // namespace details
// ---------------------------------------------------------------------------
// N-ary function call: (f expr1...exprN) , N >= 3 only
// ---------------------------------------------------------------------------
namespace details {

template<class NaryFunctor, class... Exprs>
class field_nonlinear_expr_nf {
public:
// constants:

  static const size_t N = sizeof...(Exprs);
  typedef typename range_builder<0,N>::type IndexRange;

// typedefs:

  typedef geo_element::size_type                   size_type;
  using nary_functor_traits = functor_traits<typename std::decay<NaryFunctor>::type>;
  using result_type = typename nary_functor_traits::result_type;
#ifdef TO_CLEAN
  typedef typename NaryFunctor::result_type       result_type;
#endif // TO_CLEAN

  typedef result_type                              value_type;
  typedef typename scalar_traits<value_type>::type scalar_type;
  typedef typename  float_traits<value_type>::type float_type;
  typedef rheo_default_memory_model                memory_type;
#ifdef TODO
  // TODO: extract first type Expr1 from Exprs (HOWTO extract ?) ; 
  //       also, check that all args have the same memory model
  typedef typename Expr1::memory_type              memory_type;
#endif // TODO

// alocators:

  field_nonlinear_expr_nf (const NaryFunctor& f, const Exprs&... exprs)
    : _f(f), _exprs(exprs...) {}

#ifdef TO_CLEAN
  template<class TrueFunction, class Check = typename std::enable_if<std::is_function<TrueFunction>::value, TrueFunction>::type>
  explicit field_nonlinear_expr_nf (TrueFunction f, const Exprs&... exprs)
    : _f(std::function<TrueFunction>(f)), _exprs(exprs...) {}
#endif // TO_CLEAN

// accessors:

  static const space_constant::valued_type valued_hint = space_constant::valued_tag_traits<result_type>::value;

  space_constant::valued_type valued_tag() const {
    return valued_hint; // when N >= 3 : return type should be solved at compile time
#ifdef TODO
    // TODO: when N=1,2 : possible unsolved return type until run-time:
    return details::generic_binary_traits<NaryFunctor>::valued_tag(_expr1.valued_tag(), _expr2.valued_tag());
#endif // TODO
  }

// initializers:

  template<size_t ...Is>
  bool _initialize_internal (const geo_basic<float_type,memory_type>& omega, const quadrature<float_type>& hat_x, index_list<Is...>) const {
    bool status_list[] = {std::get<Is>(_exprs).initialize (omega, hat_x)...};
    bool status = true;
    for (bool status_i : status_list) {
      status &= status_i;
    }
    return status;
  }
  bool initialize (const geo_basic<float_type,memory_type>& omega, const quadrature<float_type>& hat_x) const {
    return _initialize_internal (omega, hat_x, IndexRange());
  }
  template<size_t ...Is>
  bool _initialize_internal (const space_basic<float_type,memory_type>& Xh, index_list<Is...>) const {
    bool status_list[] = {std::get<Is>(_exprs).initialize (Xh)...};
    bool status = true;
    for (bool status_i : status_list) { status &= status_i; }
    return status;
  }
  bool initialize (const space_basic<float_type,memory_type>& Xh) const {
    return _initialize_internal (Xh, IndexRange());
  }

// evaluators:

  template<class Result, size_t ...Is>
  bool _evaluate_internal (const geo_element& K, std::vector<Result>& value, index_list<Is...>) const {
    using traits = functor_traits<typename std::decay<NaryFunctor>::type>;
    typedef std::tuple<std::vector<typename std::decay<typename traits::template arg<Is>::type>::type>...> vec_args_type;
    vec_args_type tmps;
    bool status_list[] = {std::get<Is>(_exprs).evaluate (K, std::get<Is>(tmps))...};
    value.resize (std::get<0>(tmps).size());
    for (size_type i = 0, n_value = value.size(); i < n_value; ++i) {
      value[i] = _f (std::get<Is>(tmps)[i]...);
    }
    bool status = true;
    for (bool status_i : status_list) { status &= status_i; }
    return status;
  }
  template<class Result>
  bool evaluate (const geo_element& K, std::vector<Result>& value) const {
    return _evaluate_internal (K, value, IndexRange());
  }
  template<class Result, size_t ...Is>
  bool _valued_check_internal (Result, index_list<Is...>) const {
#ifdef TO_CLEAN
    using traits = functor_traits<typename std::decay<NaryFunctor>::type>;
    // check function return type vs Result
    using return_type = typename nary_functor_traits::result_type;
#endif // TO_CLEAN
    bool are_equivalent = (decay_is_equivalent<Result,result_type>::value);
    check_macro (are_equivalent,
	"compose; incompatible function " << typename_macro(NaryFunctor) 
        << " return value " << typename_macro(result_type)
	<< " and expected value " << typename_macro(Result));
    // check function argument type vs Exprs return types via recursive calls
    bool status_list[] = { std::get<Is>(_exprs).valued_check<
    	typename nary_functor_traits::template arg<Is>::decay_type>()... };
    bool status = true;
    for (bool status_i : status_list) { status &= status_i; }
    return status;
  }
  template<class Result>
  bool valued_check() const {
    return _valued_check_internal (Result(), IndexRange());
  }
protected:
// data:
  NaryFunctor           _f;
  std::tuple<Exprs...>  _exprs;
};
// ------------------------------------------------------
// field_expr helpers, for filtering arguments
// TODO: move for all operators in exprs
// ------------------------------------------------------

template <class T>
struct is_field {
  static const bool value = false;
};
template <class T, class M>
struct is_field <field_basic<T,M> > {
  static const bool value = true;
};


template <class T>
struct is_field_constant {
  static const bool value = false;
};
template <>
struct is_field_constant<int> {
  static const bool value = true;
  typedef int type;
};

template <class F, class Check = F>
struct field_expr_traits {
  static const bool is_valid = false;
};
template <class RawExpr>
struct field_expr_traits <rheolef::field_nonlinear_expr<RawExpr> > {
   static const bool is_valid = true;
   typedef rheolef::field_nonlinear_expr<RawExpr> checked_type;
   typedef rheolef::field_nonlinear_expr<RawExpr> wrapped_type;
};
template <class T, class M>
struct field_expr_traits <field_basic<T,M> > {
   static const bool is_valid = true;
   typedef field_basic<T,M>               checked_type;
   typedef field_expr_terminal_field<T,M> wrapped_type;
};
template <class T, class M>
struct field_expr_traits <field_indirect<T,M> > {
   static const bool is_valid = true;
   typedef field_indirect<T,M>            checked_type;
   typedef field_expr_terminal_field<T,M> wrapped_type;
};
template <class T, class M>
struct field_expr_traits <field_indirect_const<T,M> > {
   static const bool is_valid = true;
   typedef field_indirect_const<T,M>      checked_type;
   typedef field_expr_terminal_field<T,M> wrapped_type;
};
template <class T, class M>
struct field_expr_traits <field_component<T,M> > {
   static const bool is_valid = true;
   typedef field_component<T,M>           checked_type;
   typedef field_expr_terminal_field<T,M> wrapped_type;
};
template <class T, class M>
struct field_expr_traits <field_component_const<T,M> > {
   static const bool is_valid = true;
   typedef field_component_const<T,M>     checked_type;
   typedef field_expr_terminal_field<T,M> wrapped_type;
};
template <class Expr>
struct field_expr_traits <field_expr<Expr> > {
   static const bool is_valid = true;
   typedef field_expr<Expr>           checked_type;
   typedef field_expr_terminal_field<typename field_expr<Expr>::scalar_type, typename field_expr<Expr>::memory_type> wrapped_type;
};
template <class Result>
struct field_expr_traits <Result(const point_basic<typename float_traits<Result>::type>&)> {
   static const bool is_valid = true;
   typedef Result(&checked_type)(const point_basic<typename float_traits<Result>::type>&);
   typedef std::pointer_to_unary_function<const point_basic<typename float_traits<Result>::type>&,Result> function_type;
   typedef field_expr_terminal_function<function_type>  wrapped_type;
};
template <class UnaryFunctor>
struct field_expr_traits
   <
       UnaryFunctor,
       typename std::enable_if
       <
	   // SFINAE filter: arity==1 and first argument_type==point
           is_point<typename UnaryFunctor::argument_type>::value
           && ! is_field<UnaryFunctor>::value // field class is also an unary_function but with different treatment in expr
          ,UnaryFunctor
       >::type
   > {
   static const bool is_valid = true;
   typedef UnaryFunctor                               checked_type;
   typedef field_expr_terminal_function<UnaryFunctor> wrapped_type;
};
template <typename Constant>
struct field_expr_traits
   <
       Constant,
       typename std::enable_if <std::is_arithmetic<Constant>::value, Constant>::type
   > {
   static const bool is_valid = true;
   typedef typename upgrade_integral_to_float<Constant>::type constant_type;
   typedef constant_type                                      checked_type;
   typedef typename float_traits<constant_type>::type         float_type;
   typedef f_constant<point_basic<float_type>,constant_type>  function_type;
   typedef field_expr_terminal_function<function_type>        wrapped_type;
};

template <class Functor, class Check = Functor>
struct wrap_function_traits {
  typedef Functor type;
};
template <class TrueFunction>
struct wrap_function_traits<TrueFunction, typename std::enable_if<std::is_function<TrueFunction>::value, TrueFunction>::type> {
  typedef std::function<TrueFunction> type;
};

} // namespace details
// ------------------------------------------------------
// compose(f,u1...uN)
// ------------------------------------------------------
template<class Function, class... Exprs>
inline
typename std::enable_if <
  sizeof...(Exprs) >= 3,
  field_nonlinear_expr<
    details::field_nonlinear_expr_nf<
      typename details::wrap_function_traits<Function>::type,
      typename details::field_expr_traits<Exprs>::wrapped_type...
    >
  >
>::type
compose (const Function& f, const Exprs&... exprs) {
  typedef typename details::wrap_function_traits<Function>::type   fun_t;
  typedef details::field_nonlinear_expr_nf<fun_t, typename details::field_expr_traits<Exprs>::wrapped_type...>   exprs_t;
  return  field_nonlinear_expr<exprs_t> (exprs_t(fun_t(f), typename details::field_expr_traits<Exprs>::wrapped_type(exprs)...));
}

} // namespace rheolef
#endif // _RHEOLEF_COMPOSE_H