1 // 2 // Copyright (c) 2000-2002 3 // Joerg Walter, Mathias Koch 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See 6 // accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // The authors gratefully acknowledge the support of 10 // GeNeSys mbH & Co. KG in producing this work. 11 // 12 13 #ifndef _BOOST_UBLAS_TRAITS_ 14 #define _BOOST_UBLAS_TRAITS_ 15 16 #include <iterator> 17 #include <complex> 18 #include <boost/config/no_tr1/cmath.hpp> 19 20 #include <boost/numeric/ublas/detail/config.hpp> 21 #include <boost/numeric/ublas/detail/iterator.hpp> 22 #include <boost/numeric/ublas/detail/returntype_deduction.hpp> 23 #ifdef BOOST_UBLAS_USE_INTERVAL 24 #include <boost/numeric/interval.hpp> 25 #endif 26 27 #include <boost/type_traits.hpp> 28 #include <complex> 29 #include <boost/typeof/typeof.hpp> 30 #include <boost/utility/enable_if.hpp> 31 #include <boost/type_traits/is_float.hpp> 32 #include <boost/type_traits/is_integral.hpp> 33 #include <boost/type_traits/is_unsigned.hpp> 34 #include <boost/mpl/and.hpp> 35 #include <boost/mpl/if.hpp> 36 #include <boost/typeof/typeof.hpp> 37 38 39 // anonymous namespace to avoid ADL issues 40 namespace { 41 template<class T> 42 typename boost::mpl::if_c<boost::is_integral<T>::value, 43 double, 44 T>::type boost_numeric_ublas_sqrt(const T & t)45 boost_numeric_ublas_sqrt (const T& t) { 46 using namespace std; 47 // we'll find either std::sqrt or else another version via ADL: 48 return sqrt (t); 49 } 50 51 template<typename T> 52 inline typename boost::disable_if< 53 boost::is_unsigned<T>, T >::type boost_numeric_ublas_abs(const T & t)54 boost_numeric_ublas_abs (const T &t ) { 55 using namespace std; 56 // force a type conversion back to T for char and short types 57 return static_cast<T>(abs( t )); 58 } 59 60 template<typename T> 61 inline typename boost::enable_if< 62 boost::is_unsigned<T>, T >::type boost_numeric_ublas_abs(const T & t)63 boost_numeric_ublas_abs (const T &t ) { 64 return t; 65 } 66 } 67 68 namespace boost { namespace numeric { namespace ublas { 69 70 71 template<typename R, typename I> 72 typename boost::enable_if< 73 mpl::and_< 74 boost::is_float<R>, 75 boost::is_integral<I> 76 >, operator +(I in1,std::complex<R> const & in2)77 std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) { 78 return R (in1) + in2; 79 } 80 81 template<typename R, typename I> 82 typename boost::enable_if< 83 mpl::and_< 84 boost::is_float<R>, 85 boost::is_integral<I> 86 >, operator +(std::complex<R> const & in1,I in2)87 std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) { 88 return in1 + R (in2); 89 } 90 91 template<typename R, typename I> 92 typename boost::enable_if< 93 mpl::and_< 94 boost::is_float<R>, 95 boost::is_integral<I> 96 >, operator -(I in1,std::complex<R> const & in2)97 std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) { 98 return R (in1) - in2; 99 } 100 101 template<typename R, typename I> 102 typename boost::enable_if< 103 mpl::and_< 104 boost::is_float<R>, 105 boost::is_integral<I> 106 >, operator -(std::complex<R> const & in1,I in2)107 std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) { 108 return in1 - R (in2); 109 } 110 111 template<typename R, typename I> 112 typename boost::enable_if< 113 mpl::and_< 114 boost::is_float<R>, 115 boost::is_integral<I> 116 >, operator *(I in1,std::complex<R> const & in2)117 std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) { 118 return R (in1) * in2; 119 } 120 121 template<typename R, typename I> 122 typename boost::enable_if< 123 mpl::and_< 124 boost::is_float<R>, 125 boost::is_integral<I> 126 >, operator *(std::complex<R> const & in1,I in2)127 std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) { 128 return in1 * R(in2); 129 } 130 131 template<typename R, typename I> 132 typename boost::enable_if< 133 mpl::and_< 134 boost::is_float<R>, 135 boost::is_integral<I> 136 >, operator /(I in1,std::complex<R> const & in2)137 std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) { 138 return R(in1) / in2; 139 } 140 141 template<typename R, typename I> 142 typename boost::enable_if< 143 mpl::and_< 144 boost::is_float<R>, 145 boost::is_integral<I> 146 >, operator /(std::complex<R> const & in1,I in2)147 std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) { 148 return in1 / R (in2); 149 } 150 151 // uBLAS assumes a common return type for all binary arithmetic operators 152 template<class X, class Y> 153 struct promote_traits { 154 typedef BOOST_TYPEOF_TPL(X() + Y()) promote_type; 155 }; 156 157 158 159 // Type traits - generic numeric properties and functions 160 template<class T> 161 struct type_traits; 162 163 // Define properties for a generic scalar type 164 template<class T> 165 struct scalar_traits { 166 typedef scalar_traits<T> self_type; 167 typedef T value_type; 168 typedef const T &const_reference; 169 typedef T &reference; 170 171 typedef T real_type; 172 typedef real_type precision_type; // we do not know what type has more precision then the real_type 173 174 static const unsigned plus_complexity = 1; 175 static const unsigned multiplies_complexity = 1; 176 177 static 178 BOOST_UBLAS_INLINE realboost::numeric::ublas::scalar_traits179 real_type real (const_reference t) { 180 return t; 181 } 182 static 183 BOOST_UBLAS_INLINE imagboost::numeric::ublas::scalar_traits184 real_type imag (const_reference /*t*/) { 185 return 0; 186 } 187 static 188 BOOST_UBLAS_INLINE conjboost::numeric::ublas::scalar_traits189 value_type conj (const_reference t) { 190 return t; 191 } 192 193 static 194 BOOST_UBLAS_INLINE type_absboost::numeric::ublas::scalar_traits195 real_type type_abs (const_reference t) { 196 return boost_numeric_ublas_abs (t); 197 } 198 static 199 BOOST_UBLAS_INLINE type_sqrtboost::numeric::ublas::scalar_traits200 value_type type_sqrt (const_reference t) { 201 // force a type conversion back to value_type for intgral types 202 return value_type (boost_numeric_ublas_sqrt (t)); 203 } 204 205 static 206 BOOST_UBLAS_INLINE norm_1boost::numeric::ublas::scalar_traits207 real_type norm_1 (const_reference t) { 208 return self_type::type_abs (t); 209 } 210 static 211 BOOST_UBLAS_INLINE norm_2boost::numeric::ublas::scalar_traits212 real_type norm_2 (const_reference t) { 213 return self_type::type_abs (t); 214 } 215 static 216 BOOST_UBLAS_INLINE norm_infboost::numeric::ublas::scalar_traits217 real_type norm_inf (const_reference t) { 218 return self_type::type_abs (t); 219 } 220 221 static 222 BOOST_UBLAS_INLINE equalsboost::numeric::ublas::scalar_traits223 bool equals (const_reference t1, const_reference t2) { 224 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON * 225 (std::max) ((std::max) (self_type::norm_inf (t1), 226 self_type::norm_inf (t2)), 227 BOOST_UBLAS_TYPE_CHECK_MIN); 228 } 229 }; 230 231 // Define default type traits, assume T is a scalar type 232 template<class T> 233 struct type_traits : scalar_traits <T> { 234 typedef type_traits<T> self_type; 235 typedef T value_type; 236 typedef const T &const_reference; 237 typedef T &reference; 238 239 typedef T real_type; 240 typedef real_type precision_type; 241 static const unsigned multiplies_complexity = 1; 242 243 }; 244 245 // Define real type traits 246 template<> 247 struct type_traits<float> : scalar_traits<float> { 248 typedef type_traits<float> self_type; 249 typedef float value_type; 250 typedef const value_type &const_reference; 251 typedef value_type &reference; 252 typedef value_type real_type; 253 typedef double precision_type; 254 }; 255 template<> 256 struct type_traits<double> : scalar_traits<double> { 257 typedef type_traits<double> self_type; 258 typedef double value_type; 259 typedef const value_type &const_reference; 260 typedef value_type &reference; 261 typedef value_type real_type; 262 typedef long double precision_type; 263 }; 264 template<> 265 struct type_traits<long double> : scalar_traits<long double> { 266 typedef type_traits<long double> self_type; 267 typedef long double value_type; 268 typedef const value_type &const_reference; 269 typedef value_type &reference; 270 typedef value_type real_type; 271 typedef value_type precision_type; 272 }; 273 274 // Define properties for a generic complex type 275 template<class T> 276 struct complex_traits { 277 typedef complex_traits<T> self_type; 278 typedef T value_type; 279 typedef const T &const_reference; 280 typedef T &reference; 281 282 typedef typename T::value_type real_type; 283 typedef real_type precision_type; // we do not know what type has more precision then the real_type 284 285 static const unsigned plus_complexity = 2; 286 static const unsigned multiplies_complexity = 6; 287 288 static 289 BOOST_UBLAS_INLINE realboost::numeric::ublas::complex_traits290 real_type real (const_reference t) { 291 return std::real (t); 292 } 293 static 294 BOOST_UBLAS_INLINE imagboost::numeric::ublas::complex_traits295 real_type imag (const_reference t) { 296 return std::imag (t); 297 } 298 static 299 BOOST_UBLAS_INLINE conjboost::numeric::ublas::complex_traits300 value_type conj (const_reference t) { 301 return std::conj (t); 302 } 303 304 static 305 BOOST_UBLAS_INLINE type_absboost::numeric::ublas::complex_traits306 real_type type_abs (const_reference t) { 307 return abs (t); 308 } 309 static 310 BOOST_UBLAS_INLINE type_sqrtboost::numeric::ublas::complex_traits311 value_type type_sqrt (const_reference t) { 312 return sqrt (t); 313 } 314 315 static 316 BOOST_UBLAS_INLINE norm_1boost::numeric::ublas::complex_traits317 real_type norm_1 (const_reference t) { 318 return self_type::type_abs (t); 319 // original computation has been replaced because a complex number should behave like a scalar type 320 // return type_traits<real_type>::type_abs (self_type::real (t)) + 321 // type_traits<real_type>::type_abs (self_type::imag (t)); 322 } 323 static 324 BOOST_UBLAS_INLINE norm_2boost::numeric::ublas::complex_traits325 real_type norm_2 (const_reference t) { 326 return self_type::type_abs (t); 327 } 328 static 329 BOOST_UBLAS_INLINE norm_infboost::numeric::ublas::complex_traits330 real_type norm_inf (const_reference t) { 331 return self_type::type_abs (t); 332 // original computation has been replaced because a complex number should behave like a scalar type 333 // return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)), 334 // type_traits<real_type>::type_abs (self_type::imag (t))); 335 } 336 337 static 338 BOOST_UBLAS_INLINE equalsboost::numeric::ublas::complex_traits339 bool equals (const_reference t1, const_reference t2) { 340 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON * 341 (std::max) ((std::max) (self_type::norm_inf (t1), 342 self_type::norm_inf (t2)), 343 BOOST_UBLAS_TYPE_CHECK_MIN); 344 } 345 }; 346 347 // Define complex type traits 348 template<> 349 struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{ 350 typedef type_traits<std::complex<float> > self_type; 351 typedef std::complex<float> value_type; 352 typedef const value_type &const_reference; 353 typedef value_type &reference; 354 typedef float real_type; 355 typedef std::complex<double> precision_type; 356 357 }; 358 template<> 359 struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{ 360 typedef type_traits<std::complex<double> > self_type; 361 typedef std::complex<double> value_type; 362 typedef const value_type &const_reference; 363 typedef value_type &reference; 364 typedef double real_type; 365 typedef std::complex<long double> precision_type; 366 }; 367 template<> 368 struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > { 369 typedef type_traits<std::complex<long double> > self_type; 370 typedef std::complex<long double> value_type; 371 typedef const value_type &const_reference; 372 typedef value_type &reference; 373 typedef long double real_type; 374 typedef value_type precision_type; 375 }; 376 377 #ifdef BOOST_UBLAS_USE_INTERVAL 378 // Define scalar interval type traits 379 template<> 380 struct type_traits<boost::numeric::interval<float> > : scalar_traits<boost::numeric::interval<float> > { 381 typedef type_traits<boost::numeric::interval<float> > self_type; 382 typedef boost::numeric::interval<float> value_type; 383 typedef const value_type &const_reference; 384 typedef value_type &reference; 385 typedef value_type real_type; 386 typedef boost::numeric::interval<double> precision_type; 387 388 }; 389 template<> 390 struct type_traits<boost::numeric::interval<double> > : scalar_traits<boost::numeric::interval<double> > { 391 typedef type_traits<boost::numeric::interval<double> > self_type; 392 typedef boost::numeric::interval<double> value_type; 393 typedef const value_type &const_reference; 394 typedef value_type &reference; 395 typedef value_type real_type; 396 typedef boost::numeric::interval<long double> precision_type; 397 }; 398 template<> 399 struct type_traits<boost::numeric::interval<long double> > : scalar_traits<boost::numeric::interval<long double> > { 400 typedef type_traits<boost::numeric::interval<long double> > self_type; 401 typedef boost::numeric::interval<long double> value_type; 402 typedef const value_type &const_reference; 403 typedef value_type &reference; 404 typedef value_type real_type; 405 typedef value_type precision_type; 406 }; 407 #endif 408 409 410 // Storage tags -- hierarchical definition of storage characteristics 411 412 struct unknown_storage_tag {}; 413 struct sparse_proxy_tag: public unknown_storage_tag {}; 414 struct sparse_tag: public sparse_proxy_tag {}; 415 struct packed_proxy_tag: public sparse_proxy_tag {}; 416 struct packed_tag: public packed_proxy_tag {}; 417 struct dense_proxy_tag: public packed_proxy_tag {}; 418 struct dense_tag: public dense_proxy_tag {}; 419 420 template<class S1, class S2> 421 struct storage_restrict_traits { 422 typedef S1 storage_category; 423 }; 424 425 template<> 426 struct storage_restrict_traits<sparse_tag, dense_proxy_tag> { 427 typedef sparse_proxy_tag storage_category; 428 }; 429 template<> 430 struct storage_restrict_traits<sparse_tag, packed_proxy_tag> { 431 typedef sparse_proxy_tag storage_category; 432 }; 433 template<> 434 struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> { 435 typedef sparse_proxy_tag storage_category; 436 }; 437 438 template<> 439 struct storage_restrict_traits<packed_tag, dense_proxy_tag> { 440 typedef packed_proxy_tag storage_category; 441 }; 442 template<> 443 struct storage_restrict_traits<packed_tag, packed_proxy_tag> { 444 typedef packed_proxy_tag storage_category; 445 }; 446 template<> 447 struct storage_restrict_traits<packed_tag, sparse_proxy_tag> { 448 typedef sparse_proxy_tag storage_category; 449 }; 450 451 template<> 452 struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> { 453 typedef sparse_proxy_tag storage_category; 454 }; 455 456 template<> 457 struct storage_restrict_traits<dense_tag, dense_proxy_tag> { 458 typedef dense_proxy_tag storage_category; 459 }; 460 template<> 461 struct storage_restrict_traits<dense_tag, packed_proxy_tag> { 462 typedef packed_proxy_tag storage_category; 463 }; 464 template<> 465 struct storage_restrict_traits<dense_tag, sparse_proxy_tag> { 466 typedef sparse_proxy_tag storage_category; 467 }; 468 469 template<> 470 struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> { 471 typedef packed_proxy_tag storage_category; 472 }; 473 template<> 474 struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> { 475 typedef sparse_proxy_tag storage_category; 476 }; 477 478 479 // Iterator tags -- hierarchical definition of storage characteristics 480 481 struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {}; 482 struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {}; 483 struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {}; 484 485 // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-) 486 template<class IC> 487 struct iterator_base_traits {}; 488 489 template<> 490 struct iterator_base_traits<std::forward_iterator_tag> { 491 template<class I, class T> 492 struct iterator_base { 493 typedef forward_iterator_base<std::forward_iterator_tag, I, T> type; 494 }; 495 }; 496 497 template<> 498 struct iterator_base_traits<std::bidirectional_iterator_tag> { 499 template<class I, class T> 500 struct iterator_base { 501 typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type; 502 }; 503 }; 504 template<> 505 struct iterator_base_traits<sparse_bidirectional_iterator_tag> { 506 template<class I, class T> 507 struct iterator_base { 508 typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type; 509 }; 510 }; 511 512 template<> 513 struct iterator_base_traits<std::random_access_iterator_tag> { 514 template<class I, class T> 515 struct iterator_base { 516 typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type; 517 }; 518 }; 519 template<> 520 struct iterator_base_traits<packed_random_access_iterator_tag> { 521 template<class I, class T> 522 struct iterator_base { 523 typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type; 524 }; 525 }; 526 template<> 527 struct iterator_base_traits<dense_random_access_iterator_tag> { 528 template<class I, class T> 529 struct iterator_base { 530 typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type; 531 }; 532 }; 533 534 template<class I1, class I2> 535 struct iterator_restrict_traits { 536 typedef I1 iterator_category; 537 }; 538 539 template<> 540 struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> { 541 typedef sparse_bidirectional_iterator_tag iterator_category; 542 }; 543 template<> 544 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> { 545 typedef sparse_bidirectional_iterator_tag iterator_category; 546 }; 547 548 template<> 549 struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> { 550 typedef sparse_bidirectional_iterator_tag iterator_category; 551 }; 552 template<> 553 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> { 554 typedef sparse_bidirectional_iterator_tag iterator_category; 555 }; 556 557 template<> 558 struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> { 559 typedef packed_random_access_iterator_tag iterator_category; 560 }; 561 template<> 562 struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> { 563 typedef packed_random_access_iterator_tag iterator_category; 564 }; 565 566 template<class I> 567 BOOST_UBLAS_INLINE increment(I & it,const I & it_end,typename I::difference_type compare,packed_random_access_iterator_tag)568 void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) { 569 it += (std::min) (compare, it_end - it); 570 } 571 template<class I> 572 BOOST_UBLAS_INLINE increment(I & it,const I &,typename I::difference_type,sparse_bidirectional_iterator_tag)573 void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) { 574 ++ it; 575 } 576 template<class I> 577 BOOST_UBLAS_INLINE increment(I & it,const I & it_end,typename I::difference_type compare)578 void increment (I &it, const I &it_end, typename I::difference_type compare) { 579 increment (it, it_end, compare, typename I::iterator_category ()); 580 } 581 582 template<class I> 583 BOOST_UBLAS_INLINE increment(I & it,const I & it_end)584 void increment (I &it, const I &it_end) { 585 #if BOOST_UBLAS_TYPE_CHECK 586 I cit (it); 587 while (cit != it_end) { 588 BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ()); 589 ++ cit; 590 } 591 #endif 592 it = it_end; 593 } 594 595 namespace detail { 596 597 // specialisation which define whether a type has a trivial constructor 598 // or not. This is used by array types. 599 template<typename T> 600 struct has_trivial_constructor : public boost::has_trivial_constructor<T> {}; 601 602 template<typename T> 603 struct has_trivial_destructor : public boost::has_trivial_destructor<T> {}; 604 605 template<typename FLT> 606 struct has_trivial_constructor<std::complex<FLT> > : public has_trivial_constructor<FLT> {}; 607 608 template<typename FLT> 609 struct has_trivial_destructor<std::complex<FLT> > : public has_trivial_destructor<FLT> {}; 610 611 } 612 613 614 /** \brief Traits class to extract type information from a constant matrix or vector CONTAINER. 615 * 616 */ 617 template < class E > 618 struct container_view_traits { 619 /// type of indices 620 typedef typename E::size_type size_type; 621 /// type of differences of indices 622 typedef typename E::difference_type difference_type; 623 624 /// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ... 625 typedef typename E::storage_category storage_category; 626 627 /// type of elements 628 typedef typename E::value_type value_type; 629 /// const reference to an element 630 typedef typename E::const_reference const_reference; 631 632 /// type used in expressions to mark a reference to this class (usually a const container_reference<const E> or the class itself) 633 typedef typename E::const_closure_type const_closure_type; 634 }; 635 636 /** \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER. 637 * 638 */ 639 template < class E > 640 struct mutable_container_traits { 641 /// reference to an element 642 typedef typename E::reference reference; 643 644 /// type used in expressions to mark a reference to this class (usually a container_reference<E> or the class itself) 645 typedef typename E::closure_type closure_type; 646 }; 647 648 /** \brief Traits class to extract type information from a matrix or vector CONTAINER. 649 * 650 */ 651 template < class E > 652 struct container_traits 653 : container_view_traits<E>, mutable_container_traits<E> { 654 655 }; 656 657 658 /** \brief Traits class to extract type information from a constant MATRIX. 659 * 660 */ 661 template < class MATRIX > 662 struct matrix_view_traits : container_view_traits <MATRIX> { 663 664 /// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag 665 typedef typename MATRIX::orientation_category orientation_category; 666 667 /// row iterator for the matrix 668 typedef typename MATRIX::const_iterator1 const_iterator1; 669 670 /// column iterator for the matrix 671 typedef typename MATRIX::const_iterator2 const_iterator2; 672 }; 673 674 /** \brief Traits class to extract additional type information from a mutable MATRIX. 675 * 676 */ 677 template < class MATRIX > 678 struct mutable_matrix_traits 679 : mutable_container_traits <MATRIX> { 680 681 /// row iterator for the matrix 682 typedef typename MATRIX::iterator1 iterator1; 683 684 /// column iterator for the matrix 685 typedef typename MATRIX::iterator2 iterator2; 686 }; 687 688 689 /** \brief Traits class to extract type information from a MATRIX. 690 * 691 */ 692 template < class MATRIX > 693 struct matrix_traits 694 : matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> { 695 }; 696 697 /** \brief Traits class to extract type information from a VECTOR. 698 * 699 */ 700 template < class VECTOR > 701 struct vector_view_traits : container_view_traits <VECTOR> { 702 703 /// iterator for the VECTOR 704 typedef typename VECTOR::const_iterator const_iterator; 705 706 /// iterator pointing to the first element 707 static beginboost::numeric::ublas::vector_view_traits708 const_iterator begin(const VECTOR & v) { 709 return v.begin(); 710 } 711 /// iterator pointing behind the last element 712 static endboost::numeric::ublas::vector_view_traits713 const_iterator end(const VECTOR & v) { 714 return v.end(); 715 } 716 717 }; 718 719 /** \brief Traits class to extract type information from a VECTOR. 720 * 721 */ 722 template < class VECTOR > 723 struct mutable_vector_traits : mutable_container_traits <VECTOR> { 724 /// iterator for the VECTOR 725 typedef typename VECTOR::iterator iterator; 726 727 /// iterator pointing to the first element 728 static beginboost::numeric::ublas::mutable_vector_traits729 iterator begin(VECTOR & v) { 730 return v.begin(); 731 } 732 733 /// iterator pointing behind the last element 734 static endboost::numeric::ublas::mutable_vector_traits735 iterator end(VECTOR & v) { 736 return v.end(); 737 } 738 }; 739 740 /** \brief Traits class to extract type information from a VECTOR. 741 * 742 */ 743 template < class VECTOR > 744 struct vector_traits 745 : vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> { 746 }; 747 748 749 // Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp 750 751 }}} 752 753 #endif 754