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
|
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_DEFINITIONS_
#define _BOOST_UBLAS_DEFINITIONS_
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/* Borrowed from boost/concept_checks.hpp
"inline" is used for ignore_unused_variable_warning()
to make sure there is no overhead with g++.
*/
template <class T> inline
void ignore_unused_variable_warning(const T&) {}
} // namespace detail
// Borrowed from Dave Abraham's noncopyable.
// I believe this should be part of utility.hpp one day...
namespace nonassignable_ // protection from unintended ADL
{
class nonassignable {
protected:
nonassignable () {}
~nonassignable () {}
private: // emphasize the following members are private
const nonassignable& operator= (const nonassignable &);
}; // nonassignable
}
typedef nonassignable_::nonassignable nonassignable;
// Assignment proxy.
// Provides temporary free assigment when LHS has no alias on RHS
template<class C>
class noalias_proxy:
private nonassignable {
public:
typedef typename C::closure_type closure_type;
BOOST_UBLAS_INLINE
noalias_proxy (C& lval):
nonassignable (), lval_ (lval) {}
BOOST_UBLAS_INLINE
noalias_proxy (const noalias_proxy& p):
nonassignable (), lval_ (p.lval_) {}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator= (const E& e) {
lval_.assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator+= (const E& e) {
lval_.plus_assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator-= (const E& e) {
lval_.minus_assign (e);
return lval_;
}
private:
closure_type lval_;
};
// Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
// noalias(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<C> noalias (C& lvalue) {
return noalias_proxy<C> (lvalue);
}
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<const C> noalias (const C& lvalue) {
return noalias_proxy<const C> (lvalue);
}
// Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
// safe(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
C& safe (C& lvalue) {
return lvalue;
}
template <class C>
BOOST_UBLAS_INLINE
const C& safe (const C& lvalue) {
return lvalue;
}
// Dimension accessors
namespace dimension {
// Generic accessors
template<unsigned dimension>
struct dimension_properties {};
template<>
struct dimension_properties<1> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &e) {
return e ().size ();
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size1 ();
}
// Note: Index functions cannot deduce dependant template parameter V or M from i
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &i) {
return i.index ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index1 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index1 ();
}
};
template<>
struct dimension_properties<2> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &) {
return 1;
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size2 ();
}
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &) {
return 1;
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index2 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index2 ();
}
};
template<unsigned dimension, class E>
BOOST_UBLAS_INLINE
typename E::size_type size (const E& e) {
return dimension_properties<dimension>::size (e);
}
template<unsigned dimension, class I>
BOOST_UBLAS_INLINE
typename I::container_type::size_type
index (const I& i) {
typedef typename I::container_type container_type;
return dimension_properties<dimension>::template index<container_type> (i);
}
// Named accessors - just syntactic sugar
template<class V>
typename V::size_type num_elements (const V &v) {
return v.size ();
}
template<class M>
typename M::size_type num_rows (const M &m) {
return m.size1 ();
}
template<class M>
typename M::size_type num_columns (const M &m) {
return m.size2 ();
}
template<class MV>
typename MV::size_type num_non_zeros (const MV &mv) {
return mv.non_zeros ();
}
}
}}}
#endif
|