File: bandwidth.hpp

package info (click to toggle)
siconos 4.4.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 78,364 kB
  • sloc: cpp: 160,975; ansic: 130,000; fortran: 33,051; python: 21,000; xml: 1,244; sh: 385; makefile: 318
file content (167 lines) | stat: -rw-r--r-- 5,262 bytes parent folder | download | duplicates (5)
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
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_NUMERIC_BINDINGS_BANDWIDTH_HPP
#define BOOST_NUMERIC_BINDINGS_BANDWIDTH_HPP

#include <boost/numeric/bindings/detail/generate_functions.hpp>
#include <boost/numeric/bindings/detail/get.hpp>
#include <boost/numeric/bindings/rank.hpp>
#include <boost/numeric/bindings/addressing_index.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/min.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/static_assert.hpp>

namespace boost {
namespace numeric {
namespace bindings {
namespace detail {

template< typename T, typename AddressingIndex, typename Enable = void >
struct bandwidth_impl {

    typedef typename tag::bandwidth_type< AddressingIndex::value > key_type;
    typedef typename result_of_get< T, key_type >::type result_type;

    static result_type invoke( const T& t ) {
        return get< key_type >( t );
    }

};

template< typename T >
struct bandwidth_impl< T, tag::lower >:
    bandwidth_impl< T, tag::addressing_index<1> > {};


template< typename T >
struct bandwidth_impl< T, tag::upper >:
    bandwidth_impl< T, tag::addressing_index<2> > {};


template< typename T, int N >
struct bandwidth_impl< T, tag::addressing_index<N>,
        typename boost::enable_if< typename mpl::and_<
            mpl::greater< tag::addressing_index<N>, rank<T> >,
            is_same_at< T, tag::bandwidth_type<1>, std::ptrdiff_t >
        >::type >::type > {

    typedef std::ptrdiff_t result_type;

    static result_type invoke( const T& t ) {
        return std::min< std::ptrdiff_t >( bandwidth_impl<T, tag::addressing_index<1> >::invoke(t), 1 );
    }

};

template< typename T, int N >
struct bandwidth_impl< T, tag::addressing_index<N>,
        typename boost::enable_if< typename mpl::and_<
            mpl::greater< tag::addressing_index<N>, rank<T> >,
            mpl::not_< is_same_at< T, tag::bandwidth_type<1>, std::ptrdiff_t > >
        >::type >::type > {

    typedef typename mpl::min<
        typename detail::property_at< T, tag::bandwidth_type<1> >::type,
        mpl::int_<1>
    >::type result_type;

    static result_type invoke( const T& t ) {
        return result_type();
    }

};

} // namespace detail


namespace result_of {

template< typename T, typename Tag = tag::addressing_index<1> >
struct bandwidth {
    BOOST_STATIC_ASSERT( (is_tag<Tag>::value) );
    typedef typename detail::bandwidth_impl< T, Tag >::result_type type;
};

} // namespace result_of

//
// Overloads for free template functions bandwidth( x, tag ), 
//
template< typename T, typename Tag >
inline typename result_of::bandwidth< const T, Tag >::type
bandwidth( const T& t, Tag ) {
    return detail::bandwidth_impl< const T, Tag >::invoke( t );
}

// Overloads for free template function bandwidth( x )
// Valid for types with rank <= 1 (scalars, vectors)
// In theory, we could provide overloads for matrices here, too, 
// if their minimal_rank is at most 1.

// template< typename T >
// typename boost::enable_if< mpl::less< rank<T>, mpl::int_<2> >,
//     typename result_of::bandwidth< const T >::type >::type
// bandwidth( const T& t ) {
//     return detail::bandwidth_impl< const T, tag::addressing_index<1> >::invoke( t );
// }

#define GENERATE_BANDWIDTH_INDEX( z, which, unused ) \
GENERATE_FUNCTIONS( bandwidth, which, tag::addressing_index<which> )

BOOST_PP_REPEAT_FROM_TO(1,3,GENERATE_BANDWIDTH_INDEX,~)

GENERATE_FUNCTIONS( bandwidth, _left, tag::addressing_index<1> )
GENERATE_FUNCTIONS( bandwidth, _right, tag::addressing_index<2> )
GENERATE_FUNCTIONS( bandwidth, _lower, tag::addressing_index<1> )
GENERATE_FUNCTIONS( bandwidth, _upper, tag::addressing_index<2> )
GENERATE_FUNCTIONS( bandwidth, _major, typename addressing_index_major<T>::type )
GENERATE_FUNCTIONS( bandwidth, _minor, typename addressing_index_minor<T>::type )

//
// Overloads for free template functions bandwidth_row( x, tag ), 
// Here, tag is assumed to be either one of
// tag::transpose, tag::no_transpose, or tag::conjugate
//
namespace result_of {

template< typename T, typename TransTag >
struct bandwidth_lower_op {
    typedef typename bandwidth<
        T,
        typename addressing_index_trans< tag::addressing_index<1>, TransTag >::type
    >::type type;
};

template< typename T, typename TransTag >
struct bandwidth_upper_op {
    typedef typename bandwidth< T, 
        typename addressing_index_trans< tag::addressing_index<2>, TransTag >::type >::type type;
};

} // namespace result_of

template< typename T, typename Tag >
inline typename result_of::bandwidth_lower_op< const T, Tag >::type
bandwidth_lower_op( const T& t, Tag ) {
    return bindings::bandwidth( t, typename addressing_index_trans< tag::addressing_index<1>, Tag >::type() );
}

template< typename T, typename Tag >
inline typename result_of::bandwidth_upper_op< const T, Tag >::type
bandwidth_upper_op( const T& t, Tag ) {
    return bindings::bandwidth( t, typename addressing_index_trans< tag::addressing_index<2>, Tag >::type() );
}

} // namespace bindings
} // namespace numeric
} // namespace boost

#endif