os/ossrv/ossrv_pub/boost_apis/boost/numeric/ublas/traits.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
//
sl@0
     2
//  Copyright (c) 2000-2002
sl@0
     3
//  Joerg Walter, Mathias Koch
sl@0
     4
//
sl@0
     5
//  Permission to use, copy, modify, distribute and sell this software
sl@0
     6
//  and its documentation for any purpose is hereby granted without fee,
sl@0
     7
//  provided that the above copyright notice appear in all copies and
sl@0
     8
//  that both that copyright notice and this permission notice appear
sl@0
     9
//  in supporting documentation.  The authors make no representations
sl@0
    10
//  about the suitability of this software for any purpose.
sl@0
    11
//  It is provided "as is" without express or implied warranty.
sl@0
    12
//
sl@0
    13
//  The authors gratefully acknowledge the support of
sl@0
    14
//  GeNeSys mbH & Co. KG in producing this work.
sl@0
    15
//
sl@0
    16
sl@0
    17
#ifndef _BOOST_UBLAS_TRAITS_
sl@0
    18
#define _BOOST_UBLAS_TRAITS_
sl@0
    19
sl@0
    20
#include <iterator>
sl@0
    21
#include <complex>
sl@0
    22
#include <cmath>
sl@0
    23
sl@0
    24
#include <boost/numeric/ublas/detail/config.hpp>
sl@0
    25
#include <boost/numeric/ublas/detail/iterator.hpp>
sl@0
    26
#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
sl@0
    27
sl@0
    28
sl@0
    29
namespace boost { namespace numeric { namespace ublas {
sl@0
    30
sl@0
    31
    // Use Joel de Guzman's return type deduction
sl@0
    32
    // uBLAS assumes a common return type for all binary arithmetic operators
sl@0
    33
    template<class X, class Y>
sl@0
    34
    struct promote_traits {
sl@0
    35
        typedef type_deduction_detail::base_result_of<X, Y> base_type;
sl@0
    36
        static typename base_type::x_type x;
sl@0
    37
        static typename base_type::y_type y;
sl@0
    38
        static const std::size_t size = sizeof (
sl@0
    39
                type_deduction_detail::test<
sl@0
    40
                    typename base_type::x_type
sl@0
    41
                  , typename base_type::y_type
sl@0
    42
                >(x + y)     // Use x+y to stand of all the arithmetic actions
sl@0
    43
            );
sl@0
    44
sl@0
    45
        static const std::size_t index = (size / sizeof (char)) - 1;
sl@0
    46
        typedef typename mpl::at_c<
sl@0
    47
            typename base_type::types, index>::type id;
sl@0
    48
        typedef typename id::type promote_type;
sl@0
    49
    };
sl@0
    50
sl@0
    51
sl@0
    52
        // Type traits - generic numeric properties and functions
sl@0
    53
    template<class T>
sl@0
    54
    struct type_traits;
sl@0
    55
        
sl@0
    56
    // Define properties for a generic scalar type
sl@0
    57
    template<class T>
sl@0
    58
    struct scalar_traits {
sl@0
    59
        typedef scalar_traits<T> self_type;
sl@0
    60
        typedef T value_type;
sl@0
    61
        typedef const T &const_reference;
sl@0
    62
        typedef T &reference;
sl@0
    63
sl@0
    64
        typedef T real_type;
sl@0
    65
        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
sl@0
    66
sl@0
    67
        static const unsigned plus_complexity = 1;
sl@0
    68
        static const unsigned multiplies_complexity = 1;
sl@0
    69
sl@0
    70
        static
sl@0
    71
        BOOST_UBLAS_INLINE
sl@0
    72
        real_type real (const_reference t) {
sl@0
    73
                return t;
sl@0
    74
        }
sl@0
    75
        static
sl@0
    76
        BOOST_UBLAS_INLINE
sl@0
    77
        real_type imag (const_reference /*t*/) {
sl@0
    78
                return 0;
sl@0
    79
        }
sl@0
    80
        static
sl@0
    81
        BOOST_UBLAS_INLINE
sl@0
    82
        value_type conj (const_reference t) {
sl@0
    83
                return t;
sl@0
    84
        }
sl@0
    85
sl@0
    86
        static
sl@0
    87
        BOOST_UBLAS_INLINE
sl@0
    88
        real_type type_abs (const_reference t) {
sl@0
    89
            return std::abs (t);    // must use explict std:: as bultin types are not in std namespace
sl@0
    90
        }
sl@0
    91
        static
sl@0
    92
        BOOST_UBLAS_INLINE
sl@0
    93
        value_type type_sqrt (const_reference t) {
sl@0
    94
               // force a type conversion back to value_type for intgral types
sl@0
    95
            return value_type (std::sqrt (t));   // must use explict std:: as bultin types are not in std namespace
sl@0
    96
        }
sl@0
    97
sl@0
    98
        static
sl@0
    99
        BOOST_UBLAS_INLINE
sl@0
   100
        real_type norm_1 (const_reference t) {
sl@0
   101
            return self_type::type_abs (t);
sl@0
   102
        }
sl@0
   103
        static
sl@0
   104
        BOOST_UBLAS_INLINE
sl@0
   105
        real_type norm_2 (const_reference t) {
sl@0
   106
            return self_type::type_abs (t);
sl@0
   107
        }
sl@0
   108
        static
sl@0
   109
        BOOST_UBLAS_INLINE
sl@0
   110
        real_type norm_inf (const_reference t) {
sl@0
   111
            return self_type::type_abs (t);
sl@0
   112
        }
sl@0
   113
sl@0
   114
        static
sl@0
   115
        BOOST_UBLAS_INLINE
sl@0
   116
        bool equals (const_reference t1, const_reference t2) {
sl@0
   117
            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
sl@0
   118
                   (std::max) ((std::max) (self_type::norm_inf (t1),
sl@0
   119
                                       self_type::norm_inf (t2)),
sl@0
   120
                             BOOST_UBLAS_TYPE_CHECK_MIN);
sl@0
   121
        }
sl@0
   122
    };
sl@0
   123
sl@0
   124
    // Define default type traits, assume T is a scalar type
sl@0
   125
    template<class T>
sl@0
   126
    struct type_traits : scalar_traits <T> {
sl@0
   127
        typedef type_traits<T> self_type;
sl@0
   128
        typedef T value_type;
sl@0
   129
        typedef const T &const_reference;
sl@0
   130
        typedef T &reference;
sl@0
   131
sl@0
   132
        typedef T real_type;
sl@0
   133
        typedef real_type precision_type;
sl@0
   134
        static const unsigned multiplies_complexity = 1;
sl@0
   135
sl@0
   136
    };
sl@0
   137
sl@0
   138
    // Define real type traits
sl@0
   139
    template<>
sl@0
   140
    struct type_traits<float> : scalar_traits<float> {
sl@0
   141
        typedef type_traits<float> self_type;
sl@0
   142
        typedef float value_type;
sl@0
   143
        typedef const value_type &const_reference;
sl@0
   144
        typedef value_type &reference;
sl@0
   145
        typedef value_type real_type;
sl@0
   146
        typedef double precision_type;
sl@0
   147
    };
sl@0
   148
    template<>
sl@0
   149
    struct type_traits<double> : scalar_traits<double> {
sl@0
   150
        typedef type_traits<double> self_type;
sl@0
   151
        typedef double value_type;
sl@0
   152
        typedef const value_type &const_reference;
sl@0
   153
        typedef value_type &reference;
sl@0
   154
        typedef value_type real_type;
sl@0
   155
        typedef long double precision_type;
sl@0
   156
    };
sl@0
   157
    template<>
sl@0
   158
    struct type_traits<long double>  : scalar_traits<long double> {
sl@0
   159
        typedef type_traits<long double> self_type;
sl@0
   160
        typedef long double value_type;
sl@0
   161
        typedef const value_type &const_reference;
sl@0
   162
        typedef value_type &reference;
sl@0
   163
        typedef value_type real_type;
sl@0
   164
        typedef value_type precision_type;
sl@0
   165
    };
sl@0
   166
sl@0
   167
    // Define properties for a generic complex type
sl@0
   168
    template<class T>
sl@0
   169
    struct complex_traits {
sl@0
   170
        typedef complex_traits<T> self_type;
sl@0
   171
        typedef T value_type;
sl@0
   172
        typedef const T &const_reference;
sl@0
   173
        typedef T &reference;
sl@0
   174
sl@0
   175
        typedef typename T::value_type real_type;
sl@0
   176
        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
sl@0
   177
sl@0
   178
        static const unsigned plus_complexity = 2;
sl@0
   179
        static const unsigned multiplies_complexity = 6;
sl@0
   180
sl@0
   181
        static
sl@0
   182
        BOOST_UBLAS_INLINE
sl@0
   183
        real_type real (const_reference t) {
sl@0
   184
                return std::real (t);
sl@0
   185
        }
sl@0
   186
        static
sl@0
   187
        BOOST_UBLAS_INLINE
sl@0
   188
        real_type imag (const_reference t) {
sl@0
   189
                return std::imag (t);
sl@0
   190
        }
sl@0
   191
        static
sl@0
   192
        BOOST_UBLAS_INLINE
sl@0
   193
        value_type conj (const_reference t) {
sl@0
   194
                return std::conj (t);
sl@0
   195
        }
sl@0
   196
sl@0
   197
        static
sl@0
   198
        BOOST_UBLAS_INLINE
sl@0
   199
        real_type type_abs (const_reference t) {
sl@0
   200
                return abs (t);
sl@0
   201
        }
sl@0
   202
        static
sl@0
   203
        BOOST_UBLAS_INLINE
sl@0
   204
        value_type type_sqrt (const_reference t) {
sl@0
   205
                return sqrt (t);
sl@0
   206
        }
sl@0
   207
sl@0
   208
        static
sl@0
   209
        BOOST_UBLAS_INLINE
sl@0
   210
        real_type norm_1 (const_reference t) {
sl@0
   211
            return type_traits<real_type>::type_abs (self_type::real (t)) +
sl@0
   212
                   type_traits<real_type>::type_abs (self_type::imag (t));
sl@0
   213
        }
sl@0
   214
        static
sl@0
   215
        BOOST_UBLAS_INLINE
sl@0
   216
        real_type norm_2 (const_reference t) {
sl@0
   217
            return self_type::type_abs (t);
sl@0
   218
        }
sl@0
   219
        static
sl@0
   220
        BOOST_UBLAS_INLINE
sl@0
   221
        real_type norm_inf (const_reference t) {
sl@0
   222
            return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
sl@0
   223
                             type_traits<real_type>::type_abs (self_type::imag (t)));
sl@0
   224
        }
sl@0
   225
sl@0
   226
        static
sl@0
   227
        BOOST_UBLAS_INLINE
sl@0
   228
        bool equals (const_reference t1, const_reference t2) {
sl@0
   229
            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
sl@0
   230
                   (std::max) ((std::max) (self_type::norm_inf (t1),
sl@0
   231
                                       self_type::norm_inf (t2)),
sl@0
   232
                             BOOST_UBLAS_TYPE_CHECK_MIN);
sl@0
   233
        }
sl@0
   234
    };
sl@0
   235
    
sl@0
   236
    // Define complex type traits
sl@0
   237
    template<>
sl@0
   238
    struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
sl@0
   239
        typedef type_traits<std::complex<float> > self_type;
sl@0
   240
        typedef std::complex<float> value_type;
sl@0
   241
        typedef const value_type &const_reference;
sl@0
   242
        typedef value_type &reference;
sl@0
   243
        typedef float real_type;
sl@0
   244
        typedef std::complex<double> precision_type;
sl@0
   245
sl@0
   246
    };
sl@0
   247
    template<>
sl@0
   248
    struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
sl@0
   249
        typedef type_traits<std::complex<double> > self_type;
sl@0
   250
        typedef std::complex<double> value_type;
sl@0
   251
        typedef const value_type &const_reference;
sl@0
   252
        typedef value_type &reference;
sl@0
   253
        typedef double real_type;
sl@0
   254
        typedef std::complex<long double> precision_type;
sl@0
   255
    };
sl@0
   256
    template<>
sl@0
   257
    struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
sl@0
   258
        typedef type_traits<std::complex<long double> > self_type;
sl@0
   259
        typedef std::complex<long double> value_type;
sl@0
   260
        typedef const value_type &const_reference;
sl@0
   261
        typedef value_type &reference;
sl@0
   262
        typedef long double real_type;
sl@0
   263
        typedef value_type precision_type;
sl@0
   264
    };
sl@0
   265
sl@0
   266
#ifdef BOOST_UBLAS_USE_INTERVAL
sl@0
   267
    // Define properties for a generic scalar interval type
sl@0
   268
    template<class T>
sl@0
   269
    struct scalar_interval_type_traits : scalar_type_traits<T> {
sl@0
   270
        typedef scalar_interval_type_traits<T> self_type;
sl@0
   271
        typedef boost::numeric::interval<float> value_type;
sl@0
   272
        typedef const value_type &const_reference;
sl@0
   273
        typedef value_type &reference;
sl@0
   274
        typedef value_type real_type;
sl@0
   275
        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
sl@0
   276
sl@0
   277
        static const unsigned plus_complexity = 1;
sl@0
   278
        static const unsigned multiplies_complexity = 1;
sl@0
   279
sl@0
   280
        static
sl@0
   281
        BOOST_UBLAS_INLINE
sl@0
   282
        real_type type_abs (const_reference t) {
sl@0
   283
            return abs (t);
sl@0
   284
        }
sl@0
   285
        static
sl@0
   286
        BOOST_UBLAS_INLINE
sl@0
   287
        value_type type_sqrt (const_reference t) {
sl@0
   288
            return sqrt (t);
sl@0
   289
        }
sl@0
   290
sl@0
   291
        static
sl@0
   292
        BOOST_UBLAS_INLINE
sl@0
   293
        real_type norm_1 (const_reference t) {
sl@0
   294
            return self_type::type_abs (t);
sl@0
   295
        }
sl@0
   296
        static
sl@0
   297
        BOOST_UBLAS_INLINE
sl@0
   298
        real_type norm_2 (const_reference t) {
sl@0
   299
            return self_type::type_abs (t);
sl@0
   300
        }
sl@0
   301
        static
sl@0
   302
        BOOST_UBLAS_INLINE
sl@0
   303
        real_type norm_inf (const_reference t) {
sl@0
   304
            return self_type::type_abs (t);
sl@0
   305
        }
sl@0
   306
sl@0
   307
        static
sl@0
   308
        BOOST_UBLAS_INLINE
sl@0
   309
        bool equals (const_reference t1, const_reference t2) {
sl@0
   310
            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
sl@0
   311
                   (std::max) ((std::max) (self_type::norm_inf (t1),
sl@0
   312
                                       self_type::norm_inf (t2)),
sl@0
   313
                             BOOST_UBLAS_TYPE_CHECK_MIN);
sl@0
   314
        }
sl@0
   315
    };
sl@0
   316
sl@0
   317
    // Define scalar interval type traits
sl@0
   318
    template<>
sl@0
   319
    struct type_traits<boost::numeric::interval<float> > : scalar_interval_type_traits<boost::numeric::interval<float> > {
sl@0
   320
        typedef type_traits<boost::numeric::interval<float> > self_type;
sl@0
   321
        typedef boost::numeric::interval<float> value_type;
sl@0
   322
        typedef const value_type &const_reference;
sl@0
   323
        typedef value_type &reference;
sl@0
   324
        typedef value_type real_type;
sl@0
   325
        typedef boost::numeric::interval<double> precision_type;
sl@0
   326
sl@0
   327
    };
sl@0
   328
    template<>
sl@0
   329
    struct type_traits<boost::numeric::interval<double> > : scalar_interval_type_traits<boost::numeric::interval<double> > {
sl@0
   330
        typedef type_traits<boost::numeric::interval<double> > self_type;
sl@0
   331
        typedef boost::numeric::interval<double> value_type;
sl@0
   332
        typedef const value_type &const_reference;
sl@0
   333
        typedef value_type &reference;
sl@0
   334
        typedef value_type real_type;
sl@0
   335
        typedef boost::numeric::interval<long double> precision_type;
sl@0
   336
    };
sl@0
   337
    template<>
sl@0
   338
    struct type_traits<boost::numeric::interval<long double> > : scalar_interval_type_traits<boost::numeric::interval<long double> > {
sl@0
   339
        typedef type_traits<boost::numeric::interval<long double> > self_type;
sl@0
   340
        typedef boost::numeric::interval<long double> value_type;
sl@0
   341
        typedef const value_type &const_reference;
sl@0
   342
        typedef value_type &reference;
sl@0
   343
        typedef value_type real_type;
sl@0
   344
        typedef value_type precision_type;
sl@0
   345
    };
sl@0
   346
sl@0
   347
#endif
sl@0
   348
sl@0
   349
sl@0
   350
    // Storage tags -- hierarchical definition of storage characteristics
sl@0
   351
sl@0
   352
    struct unknown_storage_tag {};
sl@0
   353
    struct sparse_proxy_tag: public unknown_storage_tag {};
sl@0
   354
    struct sparse_tag: public sparse_proxy_tag {};
sl@0
   355
    struct packed_proxy_tag: public sparse_proxy_tag {};
sl@0
   356
    struct packed_tag: public packed_proxy_tag {};
sl@0
   357
    struct dense_proxy_tag: public packed_proxy_tag {};
sl@0
   358
    struct dense_tag: public dense_proxy_tag {};
sl@0
   359
sl@0
   360
    template<class S1, class S2>
sl@0
   361
    struct storage_restrict_traits {
sl@0
   362
        typedef S1 storage_category;
sl@0
   363
    };
sl@0
   364
sl@0
   365
    template<>
sl@0
   366
    struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
sl@0
   367
        typedef sparse_proxy_tag storage_category;
sl@0
   368
    };
sl@0
   369
    template<>
sl@0
   370
    struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
sl@0
   371
        typedef sparse_proxy_tag storage_category;
sl@0
   372
    };
sl@0
   373
    template<>
sl@0
   374
    struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
sl@0
   375
        typedef sparse_proxy_tag storage_category;
sl@0
   376
    };
sl@0
   377
sl@0
   378
    template<>
sl@0
   379
    struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
sl@0
   380
        typedef packed_proxy_tag storage_category;
sl@0
   381
    };
sl@0
   382
    template<>
sl@0
   383
    struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
sl@0
   384
        typedef packed_proxy_tag storage_category;
sl@0
   385
    };
sl@0
   386
    template<>
sl@0
   387
    struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
sl@0
   388
        typedef sparse_proxy_tag storage_category;
sl@0
   389
    };
sl@0
   390
sl@0
   391
    template<>
sl@0
   392
    struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
sl@0
   393
        typedef sparse_proxy_tag storage_category;
sl@0
   394
    };
sl@0
   395
sl@0
   396
    template<>
sl@0
   397
    struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
sl@0
   398
        typedef dense_proxy_tag storage_category;
sl@0
   399
    };
sl@0
   400
    template<>
sl@0
   401
    struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
sl@0
   402
        typedef packed_proxy_tag storage_category;
sl@0
   403
    };
sl@0
   404
    template<>
sl@0
   405
    struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
sl@0
   406
        typedef sparse_proxy_tag storage_category;
sl@0
   407
    };
sl@0
   408
sl@0
   409
    template<>
sl@0
   410
    struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
sl@0
   411
        typedef packed_proxy_tag storage_category;
sl@0
   412
    };
sl@0
   413
    template<>
sl@0
   414
    struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
sl@0
   415
        typedef sparse_proxy_tag storage_category;
sl@0
   416
    };
sl@0
   417
sl@0
   418
sl@0
   419
    // Iterator tags -- hierarchical definition of storage characteristics
sl@0
   420
sl@0
   421
    struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
sl@0
   422
    struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
sl@0
   423
    struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
sl@0
   424
sl@0
   425
    // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
sl@0
   426
    template<class IC>
sl@0
   427
    struct iterator_base_traits {};
sl@0
   428
sl@0
   429
    template<>
sl@0
   430
    struct iterator_base_traits<std::forward_iterator_tag> {
sl@0
   431
        template<class I, class T>
sl@0
   432
        struct iterator_base {
sl@0
   433
            typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
sl@0
   434
        };
sl@0
   435
    };
sl@0
   436
sl@0
   437
    template<>
sl@0
   438
    struct iterator_base_traits<std::bidirectional_iterator_tag> {
sl@0
   439
        template<class I, class T>
sl@0
   440
        struct iterator_base {
sl@0
   441
            typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
sl@0
   442
        };
sl@0
   443
    };
sl@0
   444
    template<>
sl@0
   445
    struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
sl@0
   446
        template<class I, class T>
sl@0
   447
        struct iterator_base {
sl@0
   448
            typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
sl@0
   449
        };
sl@0
   450
    };
sl@0
   451
sl@0
   452
    template<>
sl@0
   453
    struct iterator_base_traits<std::random_access_iterator_tag> {
sl@0
   454
        template<class I, class T>
sl@0
   455
        struct iterator_base {
sl@0
   456
            typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
sl@0
   457
        };
sl@0
   458
    };
sl@0
   459
    template<>
sl@0
   460
    struct iterator_base_traits<packed_random_access_iterator_tag> {
sl@0
   461
        template<class I, class T>
sl@0
   462
        struct iterator_base {
sl@0
   463
            typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
sl@0
   464
        };
sl@0
   465
    };
sl@0
   466
    template<>
sl@0
   467
    struct iterator_base_traits<dense_random_access_iterator_tag> {
sl@0
   468
        template<class I, class T>
sl@0
   469
        struct iterator_base {
sl@0
   470
            typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
sl@0
   471
        };
sl@0
   472
    };
sl@0
   473
sl@0
   474
    template<class I1, class I2>
sl@0
   475
    struct iterator_restrict_traits {
sl@0
   476
        typedef I1 iterator_category;
sl@0
   477
    };
sl@0
   478
sl@0
   479
    template<>
sl@0
   480
    struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
sl@0
   481
        typedef sparse_bidirectional_iterator_tag iterator_category;
sl@0
   482
    };
sl@0
   483
    template<>
sl@0
   484
    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
sl@0
   485
        typedef sparse_bidirectional_iterator_tag iterator_category;
sl@0
   486
    };
sl@0
   487
sl@0
   488
    template<>
sl@0
   489
    struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
sl@0
   490
        typedef sparse_bidirectional_iterator_tag iterator_category;
sl@0
   491
    };
sl@0
   492
    template<>
sl@0
   493
    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
sl@0
   494
        typedef sparse_bidirectional_iterator_tag iterator_category;
sl@0
   495
    };
sl@0
   496
sl@0
   497
    template<>
sl@0
   498
    struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
sl@0
   499
        typedef packed_random_access_iterator_tag iterator_category;
sl@0
   500
    };
sl@0
   501
    template<>
sl@0
   502
    struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
sl@0
   503
        typedef packed_random_access_iterator_tag iterator_category;
sl@0
   504
    };
sl@0
   505
sl@0
   506
    template<class I>
sl@0
   507
    BOOST_UBLAS_INLINE
sl@0
   508
    void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
sl@0
   509
        it += (std::min) (compare, it_end - it);
sl@0
   510
    }
sl@0
   511
    template<class I>
sl@0
   512
    BOOST_UBLAS_INLINE
sl@0
   513
    void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
sl@0
   514
        ++ it;
sl@0
   515
    }
sl@0
   516
    template<class I>
sl@0
   517
    BOOST_UBLAS_INLINE
sl@0
   518
    void increment (I &it, const I &it_end, typename I::difference_type compare) {
sl@0
   519
        increment (it, it_end, compare, typename I::iterator_category ());
sl@0
   520
    }
sl@0
   521
sl@0
   522
    template<class I>
sl@0
   523
    BOOST_UBLAS_INLINE
sl@0
   524
    void increment (I &it, const I &it_end) {
sl@0
   525
#if BOOST_UBLAS_TYPE_CHECK
sl@0
   526
        I cit (it);
sl@0
   527
        while (cit != it_end) {
sl@0
   528
            BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
sl@0
   529
            ++ cit;
sl@0
   530
        }
sl@0
   531
#endif
sl@0
   532
        it = it_end;
sl@0
   533
    }
sl@0
   534
sl@0
   535
}}}
sl@0
   536
sl@0
   537
#endif