1 /*
2  *
3  * Copyright (c) Kresimir Fresl 2003
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE_1_0.txt or copy at
7  * http://www.boost.org/LICENSE_1_0.txt)
8  *
9  * Author acknowledges the support of the Faculty of Civil Engineering,
10  * University of Zagreb, Croatia.
11  *
12  */
13 
14 #ifndef BOOST_NUMERIC_BINDINGS_TRAITS_DETAIL_UTILS_HPP
15 #define BOOST_NUMERIC_BINDINGS_TRAITS_DETAIL_UTILS_HPP
16 
17 #include <iterator>
18 #include <boost/numeric/bindings/traits/type_traits.hpp>
19 
20 namespace boost { namespace numeric { namespace bindings { namespace traits {
21 
22   namespace detail {
23 
24     // complex array => real & imaginary arrays
25     template <typename CIt, typename RIt>
disentangle(CIt c,CIt c_end,RIt rr,RIt ri)26     void disentangle (CIt c, CIt c_end, RIt rr, RIt ri) {
27       for (; c != c_end; ++c, ++rr, ++ri) {
28         *rr = traits::real (*c);
29         *ri = traits::imag (*c);
30       }
31     }
32     // real & imaginary arrays => complex array
33     template <typename RIt, typename CIt>
interlace(RIt r,RIt r_end,RIt ri,CIt c)34     void interlace (RIt r, RIt r_end, RIt ri, CIt c) {
35       typedef typename std::iterator_traits<CIt>::value_type cmplx_t;
36 #ifdef BOOST_NUMERIC_BINDINGS_BY_THE_BOOK
37       for (; r != r_end; ++r, ++ri, ++c)
38         *c = cmplx_t (*r, *ri);
39 #else
40       typedef typename type_traits<cmplx_t>::real_type real_t;
41       real_t *cp = reinterpret_cast<real_t*> (&*c);
42       for (; r != r_end; ++r, ++ri) {
43         *cp = *r; ++cp;
44         *cp = *ri; ++cp;
45       }
46 #endif
47     }
48 
49     // converts real/complex to std::ptrdiff_t
to_int(float f)50     inline std::ptrdiff_t to_int (float f) { return static_cast<std::ptrdiff_t> (f); }
to_int(double d)51     inline std::ptrdiff_t to_int (double d) { return static_cast<std::ptrdiff_t> (d); }
to_int(traits::complex_f const & cf)52     inline std::ptrdiff_t to_int (traits::complex_f const& cf) {
53       return static_cast<std::ptrdiff_t> (traits::real (cf));
54     }
to_int(traits::complex_d const & cd)55     inline std::ptrdiff_t to_int (traits::complex_d const& cd) {
56       return static_cast<std::ptrdiff_t> (traits::real (cd));
57     }
58 
59   }
60 
61 }}}}
62 
63 #endif
64