traits.hpp 25 KB

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