You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.1 KiB
128 lines
3.1 KiB
6 years ago
|
//
|
||
|
// 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
|