// // Copyright (c) 2003 Kresimir Fresl // 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_DETAIL_ARRAY_HPP #define BOOST_NUMERIC_BINDINGS_DETAIL_ARRAY_HPP #include #include #include /* very simple dynamic array class which is used in `higher level' bindings functions for pivot and work arrays Namely, there are (at least) two versions of all bindings functions where called LAPACK function expects work and/or pivot array, e.g. `lower' level (user should provide work and pivot arrays): int sysv (SymmA& a, IVec& i, MatrB& b, Work& w); `higher' level (with `internal' work and pivot arrays): int sysv (SymmA& a, MatrB& b); Probably you ask why I didn't use std::vector. There are two reasons. First is efficiency -- std::vector's constructor initialises vector elements. Second is consistency. LAPACK functions use `info' parameter as an error indicator. On the other hand, std::vector's allocator can throw an exception if memory allocation fails. detail::array's constructor uses `new (nothrow)' which returns 0 if allocation fails. So I can check whether array::storage == 0 and return appropriate error in `info'.*/ namespace boost { namespace numeric { namespace bindings { namespace detail { template class array : private noncopyable { public: typedef std::ptrdiff_t size_type ; array (size_type n) { stg = new (std::nothrow) T[n]; sz = (stg != 0) ? n : 0; } ~array() { delete[] stg; } size_type size() const { return sz; } bool valid() const { return stg != 0; } void resize (int n) { delete[] stg; stg = new (std::nothrow) T[n]; sz = (stg != 0) ? n : 0; } T* storage() { return stg; } T const* storage() const { return stg; } T& operator[] (int i) { return stg[i]; } T const& operator[] (int i) const { return stg[i]; } private: size_type sz; T* stg; }; template< typename T, typename Id, typename Enable > struct adaptor< array< T >, Id, Enable > { typedef typename copy_const< Id, T >::type value_type; typedef mpl::map< mpl::pair< tag::value_type, value_type >, mpl::pair< tag::entity, tag::vector >, mpl::pair< tag::size_type<1>, std::ptrdiff_t >, mpl::pair< tag::data_structure, tag::linear_array >, mpl::pair< tag::stride_type<1>, tag::contiguous > > property_map; static std::ptrdiff_t size1( const Id& t ) { return t.size(); } static value_type* begin_value( Id& t ) { return t.storage(); } static value_type* end_value( Id& t ) { return t.storage() + t.size(); } }; } // namespace detail } // namespace bindings } // namespace numeric } // namespace boost #endif