2
0
mirror of https://github.com/boostorg/ublas.git synced 2026-02-13 00:42:14 +00:00

- add optimizations for trivial constructors to array types

- add initializing constructors to matix<> and vector<>
  usage: matrix<double> m(3,3,5.0); vector<double> v(3,5.0);
- avoid constructor call for std::complex<T>, user can specialize
  detail::has_trivial_constructor<T> to control this behavior

svn path=/trunk/boost/boost/numeric/ublas/; revision=37209
This commit is contained in:
Gunter Winkler
2007-03-16 22:39:17 +00:00
parent cb2ecedfdf
commit 1bd53f2ad6
5 changed files with 61 additions and 27 deletions

View File

@@ -267,11 +267,19 @@ namespace boost { namespace numeric { namespace ublas {
// return (std::min) (size1, size2);
// }
// #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
template<class T>
// need two types here because different containers can have
// different size_types (especially sparse types)
template<class T1, class T2>
BOOST_UBLAS_INLINE
// Kresimir Fresl and Dan Muller reported problems with COMO.
// We better change the signature instead of libcomo ;-)
// const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
T1 same_impl_ex (const T1 &size1, const T2 &size2, const char *file, int line) {
BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
return (size1 < size2)?(size1):(size2);
}
template<class T>
BOOST_UBLAS_INLINE
T same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
return (std::min) (size1, size2);

View File

@@ -97,6 +97,10 @@ namespace boost { namespace numeric { namespace ublas {
matrix_container<self_type> (),
size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
}
matrix (size_type size1, size_type size2, const value_type &init):
matrix_container<self_type> (),
size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
}
BOOST_UBLAS_INLINE
matrix (size_type size1, size_type size2, const array_type &data):
matrix_container<self_type> (),

View File

@@ -23,6 +23,7 @@
#endif
#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/detail/iterator.hpp>
@@ -63,19 +64,15 @@ namespace boost { namespace numeric { namespace ublas {
explicit BOOST_UBLAS_INLINE
unbounded_array (size_type size, const ALLOC &a = ALLOC()):
alloc_(a), size_ (size) {
if (size_) {
data_ = alloc_.allocate (size_);
// ISSUE some compilers may zero POD here
#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
// array form fails on some compilers due to size cookie, is it standard conforming?
new (data_) value_type[size_];
#else
for (pointer d = data_; d != data_ + size_; ++d)
new (d) value_type;
#endif
}
else
data_ = 0;
if (size_) {
data_ = alloc_.allocate (size_);
if (not detail::has_trivial_constructor<T>::value) {
for (pointer d = data_; d != data_ + size_; ++d)
alloc_.construct(d, value_type());
}
}
else
data_ = 0;
}
// No value initialised, but still be default constructed
BOOST_UBLAS_INLINE
@@ -101,9 +98,12 @@ namespace boost { namespace numeric { namespace ublas {
BOOST_UBLAS_INLINE
~unbounded_array () {
if (size_) {
const iterator i_end = end();
for (iterator i = begin (); i != i_end; ++i) {
iterator_destroy (i);
if (not detail::has_trivial_destructor<T>::value) {
// std::_Destroy (begin(), end(), alloc_);
const iterator i_end = end();
for (iterator i = begin (); i != i_end; ++i) {
iterator_destroy (i);
}
}
alloc_.deallocate (data_, size_);
}
@@ -137,20 +137,18 @@ namespace boost { namespace numeric { namespace ublas {
}
}
else {
// ISSUE some compilers may zero POD here
#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
// array form fails on some compilers due to size cookie, is it standard conforming?
new (data_) value_type[size];
#else
for (pointer di = data_; di != data_ + size; ++di)
new (di) value_type;
#endif
if (not detail::has_trivial_constructor<T>::value) {
for (pointer di = data_; di != data_ + size; ++di)
alloc_.construct (di, value_type());
}
}
}
if (size_) {
for (pointer si = p_data; si != p_data + size_; ++si)
alloc_.destroy (si);
if (not detail::has_trivial_destructor<T>::value) {
for (pointer si = p_data; si != p_data + size_; ++si)
alloc_.destroy (si);
}
alloc_.deallocate (p_data, size_);
}

View File

@@ -25,6 +25,8 @@
#include <boost/numeric/ublas/detail/iterator.hpp>
#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
#include <boost/type_traits.hpp>
#include <complex>
namespace boost { namespace numeric { namespace ublas {
@@ -485,6 +487,24 @@ namespace boost { namespace numeric { namespace ublas {
it = it_end;
}
namespace detail {
// specialisation which define whether a type has a trivial constructor
// or not. This is used by array types.
template<typename T>
struct has_trivial_constructor : public boost::has_trivial_constructor<T> {};
template<typename T>
struct has_trivial_destructor : public boost::has_trivial_destructor<T> {};
template<typename FLT>
struct has_trivial_constructor<std::complex<FLT> > : public boost::true_type {};
template<typename FLT>
struct has_trivial_destructor<std::complex<FLT> > : public boost::true_type {};
}
}}}
#endif

View File

@@ -63,6 +63,10 @@ namespace boost { namespace numeric { namespace ublas {
vector_container<self_type> (),
data_ (data) {}
BOOST_UBLAS_INLINE
vector (size_type size, const value_type &init):
vector_container<self_type> (),
data_ (size, init) {}
BOOST_UBLAS_INLINE
vector (const vector &v):
vector_container<self_type> (),
data_ (v.data_) {}