Files
Timed-Altarica-To-Fiacre-Tr…/sdk/boost/numeric/bindings/detail/array.hpp

128 lines
3.1 KiB
C++
Raw Normal View History

2018-12-06 16:01:56 +01:00
//
// 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 <new>
#include <boost/noncopyable.hpp>
#include <boost/numeric/bindings/detail/adaptor.hpp>
/*
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 <typename T>
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