Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / accumulators / numeric / functional.hpp @ 2486

History | View | Annotate | Download (22.2 kB)

1
///////////////////////////////////////////////////////////////////////////////
2
/// \file functional.hpp
3
///
4
//  Copyright 2005 Eric Niebler. Distributed under the Boost
5
//  Software License, Version 1.0. (See accompanying file
6
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

    
8
#ifndef BOOST_NUMERIC_FUNCTIONAL_HPP_EAN_08_12_2005
9
#define BOOST_NUMERIC_FUNCTIONAL_HPP_EAN_08_12_2005
10

    
11
#include <limits>
12
#include <functional>
13
#include <boost/static_assert.hpp>
14
#include <boost/mpl/if.hpp>
15
#include <boost/mpl/and.hpp>
16
#include <boost/type_traits/remove_const.hpp>
17
#include <boost/type_traits/add_reference.hpp>
18
#include <boost/type_traits/is_empty.hpp>
19
#include <boost/type_traits/is_integral.hpp>
20
#include <boost/type_traits/is_floating_point.hpp>
21
#include <boost/utility/enable_if.hpp>
22
#include <boost/typeof/typeof.hpp>
23
#include <boost/accumulators/accumulators_fwd.hpp>
24
#include <boost/accumulators/numeric/functional_fwd.hpp>
25
#include <boost/accumulators/numeric/detail/function1.hpp>
26
#include <boost/accumulators/numeric/detail/function2.hpp>
27
#include <boost/accumulators/numeric/detail/pod_singleton.hpp>
28

    
29
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
30
# include <boost/accumulators/numeric/functional/vector.hpp>
31
#endif
32

    
33
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_VALARRAY_SUPPORT
34
# include <boost/accumulators/numeric/functional/valarray.hpp>
35
#endif
36

    
37
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_COMPLEX_SUPPORT
38
# include <boost/accumulators/numeric/functional/complex.hpp>
39
#endif
40

    
41
/// INTERNAL ONLY
42
///
43
#define BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
44

    
45
#ifdef BOOST_NUMERIC_FUNCTIONAL_DOXYGEN_INVOKED
46
// Hack to make Doxygen show the inheritance relationships
47
/// INTERNAL ONLY
48
///
49
namespace std
50
{
51
    /// INTERNAL ONLY
52
    ///
53
    template<class Arg, class Ret> struct unary_function {};
54
    /// INTERNAL ONLY
55
    ///
56
    template<class Left, class Right, class Ret> struct binary_function {};
57
}
58
#endif
59

    
60
namespace boost { namespace numeric
61
{
62
    namespace functional
63
    {
64
        /// INTERNAL ONLY
65
        ///
66
        template<typename A0, typename A1>
67
        struct are_integral
68
          : mpl::and_<is_integral<A0>, is_integral<A1> >
69
        {};
70

    
71
        template<typename Left, typename Right>
72
        struct left_ref
73
        {
74
            typedef Left &type;
75
        };
76

    
77
        namespace detail
78
        {
79
            template<typename T>
80
            T &lvalue_of();
81
        }
82
    }
83

    
84
    // TODO: handle complex weight, valarray, MTL vectors
85

    
86
    /// INTERNAL ONLY
87
    ///
88
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(Name, Op)                                      \
89
    namespace functional                                                                        \
90
    {                                                                                           \
91
        template<typename Arg>                                                                  \
92
        struct result_of_ ## Name                                                               \
93
        {                                                                                       \
94
            BOOST_TYPEOF_NESTED_TYPEDEF_TPL(                                                    \
95
                nested                                                                          \
96
              , Op boost::numeric::functional::detail::lvalue_of<Arg>()                         \
97
            )                                                                                   \
98
            typedef typename nested::type type;                                                 \
99
        };                                                                                      \
100
        template<typename Arg, typename EnableIf>                                               \
101
        struct Name ## _base                                                                    \
102
          : std::unary_function<                                                                \
103
                typename remove_const<Arg>::type                                                \
104
              , typename result_of_ ## Name<Arg>::type                                          \
105
            >                                                                                   \
106
        {                                                                                       \
107
            typename result_of_ ## Name<Arg>::type operator ()(Arg &arg) const                  \
108
            {                                                                                   \
109
                return Op arg;                                                                  \
110
            }                                                                                   \
111
        };                                                                                      \
112
        template<typename Arg, typename ArgTag>                                                 \
113
        struct Name                                                                             \
114
          : Name ## _base<Arg, void>                                                            \
115
        {};                                                                                     \
116
    }                                                                                           \
117
    namespace op                                                                                \
118
    {                                                                                           \
119
        struct Name                                                                             \
120
          : boost::detail::function1<functional::Name<_, functional::tag<_> > >                 \
121
        {};                                                                                     \
122
    }                                                                                           \
123
    namespace                                                                                   \
124
    {                                                                                           \
125
        op::Name const &Name = boost::detail::pod_singleton<op::Name>::instance;                \
126
    }                                                                                           \
127
    /**/
128

    
129
    /// INTERNAL ONLY
130
    ///
131
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(Name, Op, RetType)                            \
132
    namespace functional                                                                        \
133
    {                                                                                           \
134
        template<typename Left, typename Right, typename EnableIf>                              \
135
        struct result_of_ ## Name                                                               \
136
        {                                                                                       \
137
            RetType(Left, Op, Right)                                                            \
138
        };                                                                                      \
139
        template<typename Left, typename Right, typename EnableIf>                              \
140
        struct Name ## _base                                                                    \
141
          : std::binary_function<                                                               \
142
                typename remove_const<Left>::type                                               \
143
              , typename remove_const<Right>::type                                              \
144
              , typename result_of_ ## Name<Left, Right>::type                                  \
145
            >                                                                                   \
146
        {                                                                                       \
147
            typename result_of_ ## Name<Left, Right>::type                                      \
148
            operator ()(Left &left, Right &right) const                                         \
149
            {                                                                                   \
150
                return left Op right;                                                           \
151
            }                                                                                   \
152
        };                                                                                      \
153
        template<typename Left, typename Right, typename LeftTag, typename RightTag>            \
154
        struct Name                                                                             \
155
          : Name ## _base<Left, Right, void>                                                    \
156
        {};                                                                                     \
157
    }                                                                                           \
158
    namespace op                                                                                \
159
    {                                                                                           \
160
        struct Name                                                                             \
161
          : boost::detail::function2<                                                           \
162
                functional::Name<_1, _2, functional::tag<_1>, functional::tag<_2> >             \
163
            >                                                                                   \
164
        {};                                                                                     \
165
    }                                                                                           \
166
    namespace                                                                                   \
167
    {                                                                                           \
168
        op::Name const &Name = boost::detail::pod_singleton<op::Name>::instance;                \
169
    }                                                                                           \
170
    BOOST_ACCUMULATORS_IGNORE_GLOBAL(Name)                                                      \
171
    /**/
172

    
173
    /// INTERNAL ONLY
174
    ///
175
#define BOOST_NUMERIC_FUNCTIONAL_DEDUCED(Left, Op, Right)                                       \
176
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(                                                            \
177
        nested                                                                                  \
178
      , boost::numeric::functional::detail::lvalue_of<Left>() Op                                \
179
        boost::numeric::functional::detail::lvalue_of<Right>()                                  \
180
    )                                                                                           \
181
    typedef typename nested::type type;                                                         \
182
    /**/
183

    
184
    /// INTERNAL ONLY
185
    ///
186
#define BOOST_NUMERIC_FUNCTIONAL_LEFT(Left, Op, Right)                                          \
187
    typedef Left &type;                                                                         \
188
    /**/
189

    
190
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(plus, +, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
191
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(minus, -, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
192
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(multiplies, *, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
193
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(divides, /, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
194
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(modulus, %, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
195
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(greater, >, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
196
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(greater_equal, >=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
197
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(less, <, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
198
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(less_equal, <=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
199
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(equal_to, ==, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
200
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(not_equal_to, !=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
201

    
202
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(assign, =, BOOST_NUMERIC_FUNCTIONAL_LEFT)
203
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(plus_assign, +=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
204
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(minus_assign, -=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
205
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(multiplies_assign, *=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
206
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(divides_assign, /=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
207
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(modulus_assign, %=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
208

    
209
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(unary_plus, +)
210
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(unary_minus, -)
211
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(complement, ~)
212
    BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(logical_not, !)
213

    
214
#undef BOOST_NUMERIC_FUNCTIONAL_LEFT
215
#undef BOOST_NUMERIC_FUNCTIONAL_DEDUCED
216
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP
217
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP
218

    
219
    namespace functional
220
    {
221
        template<typename Left, typename Right, typename EnableIf>
222
        struct min_assign_base
223
          : std::binary_function<Left, Right, void>
224
        {
225
            void operator ()(Left &left, Right &right) const
226
            {
227
                if(numeric::less(right, left))
228
                {
229
                    left = right;
230
                }
231
            }
232
        };
233

    
234
        template<typename Left, typename Right, typename EnableIf>
235
        struct max_assign_base
236
          : std::binary_function<Left, Right, void>
237
        {
238
            void operator ()(Left &left, Right &right) const
239
            {
240
                if(numeric::greater(right, left))
241
                {
242
                    left = right;
243
                }
244
            }
245
        };
246

    
247
        template<typename Left, typename Right, typename EnableIf>
248
        struct fdiv_base
249
          : functional::divides<Left, Right>
250
        {};
251

    
252
        // partial specialization that promotes the arguments to double for
253
        // integral division.
254
        template<typename Left, typename Right>
255
        struct fdiv_base<Left, Right, typename enable_if<are_integral<Left, Right> >::type>
256
          : functional::divides<double const, double const>
257
        {};
258

    
259
        template<typename To, typename From, typename EnableIf>
260
        struct promote_base
261
          : std::unary_function<From, To>
262
        {
263
            To operator ()(From &from) const
264
            {
265
                return from;
266
            }
267
        };
268

    
269
        template<typename ToFrom>
270
        struct promote_base<ToFrom, ToFrom, void>
271
          : std::unary_function<ToFrom, ToFrom>
272
        {
273
            ToFrom &operator ()(ToFrom &tofrom)
274
            {
275
                return tofrom;
276
            }
277
        };
278

    
279
        template<typename Arg, typename EnableIf>
280
        struct as_min_base
281
          : std::unary_function<Arg, typename remove_const<Arg>::type>
282
        {
283
            BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
284

    
285
            typename remove_const<Arg>::type operator ()(Arg &) const
286
            {
287
                return (std::numeric_limits<typename remove_const<Arg>::type>::min)();
288
            }
289
        };
290

    
291
        template<typename Arg>
292
        struct as_min_base<Arg, typename enable_if<is_floating_point<Arg> >::type>
293
          : std::unary_function<Arg, typename remove_const<Arg>::type>
294
        {
295
            BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
296

    
297
            typename remove_const<Arg>::type operator ()(Arg &) const
298
            {
299
                return -(std::numeric_limits<typename remove_const<Arg>::type>::max)();
300
            }
301
        };
302

    
303
        template<typename Arg, typename EnableIf>
304
        struct as_max_base
305
          : std::unary_function<Arg, typename remove_const<Arg>::type>
306
        {
307
            BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
308

    
309
            typename remove_const<Arg>::type operator ()(Arg &) const
310
            {
311
                return (std::numeric_limits<typename remove_const<Arg>::type>::max)();
312
            }
313
        };
314

    
315
        template<typename Arg, typename EnableIf>
316
        struct as_zero_base
317
          : std::unary_function<Arg, typename remove_const<Arg>::type>
318
        {
319
            typename remove_const<Arg>::type operator ()(Arg &) const
320
            {
321
                return numeric::zero<typename remove_const<Arg>::type>::value;
322
            }
323
        };
324

    
325
        template<typename Arg, typename EnableIf>
326
        struct as_one_base
327
          : std::unary_function<Arg, typename remove_const<Arg>::type>
328
        {
329
            typename remove_const<Arg>::type operator ()(Arg &) const
330
            {
331
                return numeric::one<typename remove_const<Arg>::type>::value;
332
            }
333
        };
334

    
335
        template<typename To, typename From, typename ToTag, typename FromTag>
336
        struct promote
337
          : promote_base<To, From, void>
338
        {};
339

    
340
        template<typename Left, typename Right, typename LeftTag, typename RightTag>
341
        struct min_assign
342
          : min_assign_base<Left, Right, void>
343
        {};
344

    
345
        template<typename Left, typename Right, typename LeftTag, typename RightTag>
346
        struct max_assign
347
          : max_assign_base<Left, Right, void>
348
        {};
349

    
350
        template<typename Left, typename Right, typename LeftTag, typename RightTag>
351
        struct fdiv
352
          : fdiv_base<Left, Right, void>
353
        {};
354

    
355
        /// INTERNAL ONLY 
356
        /// For back-compat only. Use fdiv.
357
        template<typename Left, typename Right, typename LeftTag, typename RightTag>
358
        struct average
359
          : fdiv<Left, Right, LeftTag, RightTag>
360
        {};
361

    
362
        template<typename Arg, typename Tag>
363
        struct as_min
364
          : as_min_base<Arg, void>
365
        {};
366

    
367
        template<typename Arg, typename Tag>
368
        struct as_max
369
          : as_max_base<Arg, void>
370
        {};
371

    
372
        template<typename Arg, typename Tag>
373
        struct as_zero
374
          : as_zero_base<Arg, void>
375
        {};
376

    
377
        template<typename Arg, typename Tag>
378
        struct as_one
379
          : as_one_base<Arg, void>
380
        {};
381
    }
382

    
383
    namespace op
384
    {
385
        template<typename To>
386
        struct promote
387
          : boost::detail::function1<functional::promote<To, _, typename functional::tag<To>::type, functional::tag<_> > >
388
        {};
389

    
390
        struct min_assign
391
          : boost::detail::function2<functional::min_assign<_1, _2, functional::tag<_1>, functional::tag<_2> > >
392
        {};
393

    
394
        struct max_assign
395
          : boost::detail::function2<functional::max_assign<_1, _2, functional::tag<_1>, functional::tag<_2> > >
396
        {};
397

    
398
        struct fdiv
399
          : boost::detail::function2<functional::fdiv<_1, _2, functional::tag<_1>, functional::tag<_2> > >
400
        {};
401

    
402
        /// INTERNAL ONLY
403
        struct average
404
          : boost::detail::function2<functional::fdiv<_1, _2, functional::tag<_1>, functional::tag<_2> > >
405
        {};
406

    
407
        struct as_min
408
          : boost::detail::function1<functional::as_min<_, functional::tag<_> > >
409
        {};
410

    
411
        struct as_max
412
          : boost::detail::function1<functional::as_max<_, functional::tag<_> > >
413
        {};
414

    
415
        struct as_zero
416
          : boost::detail::function1<functional::as_zero<_, functional::tag<_> > >
417
        {};
418

    
419
        struct as_one
420
          : boost::detail::function1<functional::as_one<_, functional::tag<_> > >
421
        {};
422
    }
423

    
424
    namespace
425
    {
426
        op::min_assign const &min_assign = boost::detail::pod_singleton<op::min_assign>::instance;
427
        op::max_assign const &max_assign = boost::detail::pod_singleton<op::max_assign>::instance;
428
        op::fdiv const &fdiv = boost::detail::pod_singleton<op::fdiv>::instance;
429
        op::fdiv const &average = boost::detail::pod_singleton<op::fdiv>::instance; ///< INTERNAL ONLY
430
        op::as_min const &as_min = boost::detail::pod_singleton<op::as_min>::instance;
431
        op::as_max const &as_max = boost::detail::pod_singleton<op::as_max>::instance;
432
        op::as_zero const &as_zero = boost::detail::pod_singleton<op::as_zero>::instance;
433
        op::as_one const &as_one = boost::detail::pod_singleton<op::as_one>::instance;
434

    
435
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(min_assign)
436
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(max_assign)
437
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(fdiv)
438
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(average)
439
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_min)
440
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_max)
441
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_zero)
442
        BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_one)
443
    }
444

    
445
    ///////////////////////////////////////////////////////////////////////////////
446
    // promote
447
    template<typename To, typename From>
448
    typename lazy_disable_if<is_const<From>, mpl::if_<is_same<To, From>, To &, To> >::type
449
    promote(From &from)
450
    {
451
        return functional::promote<To, From>()(from);
452
    }
453

    
454
    template<typename To, typename From>
455
    typename mpl::if_<is_same<To const, From const>, To const &, To const>::type
456
    promote(From const &from)
457
    {
458
        return functional::promote<To const, From const>()(from);
459
    }
460

    
461
    template<typename T>
462
    struct default_
463
    {
464
        typedef default_ type;
465
        typedef T value_type;
466
        static T const value;
467

    
468
        operator T const & () const
469
        {
470
            return default_::value;
471
        }
472
    };
473

    
474
    template<typename T>
475
    T const default_<T>::value = T();
476

    
477
    template<typename T>
478
    struct one
479
    {
480
        typedef one type;
481
        typedef T value_type;
482
        static T const value;
483

    
484
        operator T const & () const
485
        {
486
            return one::value;
487
        }
488
    };
489

    
490
    template<typename T>
491
    T const one<T>::value = T(1);
492

    
493
    template<typename T>
494
    struct zero
495
    {
496
        typedef zero type;
497
        typedef T value_type;
498
        static T const value;
499

    
500
        operator T const & () const
501
        {
502
            return zero::value;
503
        }
504
    };
505

    
506
    template<typename T>
507
    T const zero<T>::value = T();
508

    
509
    template<typename T>
510
    struct one_or_default
511
      : mpl::if_<is_empty<T>, default_<T>, one<T> >::type
512
    {};
513

    
514
    template<typename T>
515
    struct zero_or_default
516
      : mpl::if_<is_empty<T>, default_<T>, zero<T> >::type
517
    {};
518

    
519
}} // namespace boost::numeric
520

    
521
#endif