traits.hpp 24 KB

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