// // Copyright (c) 2009 Rutger ter Borg // // 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) // #ifndef BOOST_NUMERIC_BINDINGS_BEGIN_HPP #define BOOST_NUMERIC_BINDINGS_BEGIN_HPP #include #include #include #include #include #include #include namespace boost { namespace numeric { namespace bindings { namespace detail { template< typename T, typename Tag > struct begin_impl {}; template< typename T > struct begin_impl< T, tag::value > { typedef typename bindings::value_type< T>::type* result_type; static result_type invoke( T& t ) { return adaptor_access::begin_value( t ); } }; template< typename T, int Dimension > struct begin_impl > { typedef tag::addressing_index tag_type; typedef linear_iterator< typename bindings::value_type< T>::type, typename result_of::stride< T, tag_type >::type > result_type; static result_type invoke( T& t ) { return result_type( adaptor_access::begin_value( t ), bindings::stride(t, tag_type() ) ); } }; template< typename T > struct begin_impl< T, tag::index_major > { typedef typename detail::property_at< T, tag::index_type >::type* result_type; static result_type invoke( T& t ) { return adaptor_access::begin_index_major( t ); } }; template< typename T > struct begin_impl< T, tag::compressed_index_major > { typedef typename detail::property_at< T, tag::index_type >::type* result_type; static result_type invoke( T& t ) { return adaptor_access::begin_compressed_index_major( t ); } }; template< typename T > struct begin_impl< T, tag::index_minor > { typedef typename detail::property_at< T, tag::index_type >::type* result_type; static result_type invoke( T& t ) { return adaptor_access::begin_index_minor( t ); } }; } // namespace detail namespace result_of { template< typename T, typename Tag = tag::addressing_index<1> > struct begin { BOOST_STATIC_ASSERT( (is_tag::value) ); typedef typename detail::begin_impl::result_type type; }; } // namespace result_of // // Free Functions // // // Overloads like begin( t, tag ) // template< typename T, typename Tag > inline typename result_of::begin::type begin( T& t, Tag ) { return detail::begin_impl::invoke( t ); } template< typename T, typename Tag > inline typename result_of::begin::type begin( const T& t, Tag ) { return detail::begin_impl::invoke( t ); } // Overloads for types with rank <= 1 (scalars, vectors) // In theory, we could provide overloads for matrices here, too, // if their minimal_rank is at most 1. template< typename T > typename boost::enable_if< mpl::less< rank, mpl::int_<2> >, typename result_of::begin< T >::type >::type begin( T& t ) { return detail::begin_impl< T, tag::addressing_index<1> >::invoke( t ); } template< typename T > typename boost::enable_if< mpl::less< rank, mpl::int_<2> >, typename result_of::begin< const T >::type >::type begin( const T& t ) { return detail::begin_impl< const T, tag::addressing_index<1> >::invoke( t ); } #define GENERATE_BEGIN_INDEX( z, which, unused ) \ GENERATE_FUNCTIONS( begin, which, tag::addressing_index ) BOOST_PP_REPEAT_FROM_TO(1,3,GENERATE_BEGIN_INDEX,~) GENERATE_FUNCTIONS( begin, _value, tag::value ) GENERATE_FUNCTIONS( begin, _row, tag::addressing_index<1> ) GENERATE_FUNCTIONS( begin, _column, tag::addressing_index<2> ) GENERATE_FUNCTIONS( begin, _index_major, tag::index_major ) GENERATE_FUNCTIONS( begin, _compressed_index_major, tag::compressed_index_major ) GENERATE_FUNCTIONS( begin, _index_minor, tag::index_minor ) } // namespace bindings } // namespace numeric } // namespace boost #endif