+++ /dev/null
-
-CML - Configurable Math Library
-http://www.cmldev.net/
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
#ifndef dynamic_1D_h
#define dynamic_1D_h
-#include <vector>
+#include <memory>
#include <cml/core/common.h>
#include <cml/dynamic.h>
/* Record the generator: */
typedef dynamic<Alloc> generator_type;
- /* Array implementation: */
- typedef std::vector<Element,allocator_type> array_impl;
-
/* Standard: */
- typedef typename array_impl::value_type value_type;
- typedef typename array_impl::pointer pointer;
- typedef typename array_impl::reference reference;
- typedef typename array_impl::const_reference const_reference;
- typedef typename array_impl::const_pointer const_pointer;
+ typedef typename allocator_type::value_type value_type;
+ typedef typename allocator_type::pointer pointer;
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+ typedef typename allocator_type::const_pointer const_pointer;
/* For matching by memory type: */
typedef dynamic_memory_tag memory_tag;
public:
/** Construct a dynamic array with no size. */
- dynamic_1D() {}
+ dynamic_1D() : m_size(0), m_data(0), m_alloc() {}
/** Construct a dynamic array given the size. */
- explicit dynamic_1D(size_t size) : m_data(size) {}
+ explicit dynamic_1D(size_t size) : m_size(0), m_data(0), m_alloc() {
+ this->resize(size);
+ }
+
+ /** Copy construct a dynamic array. */
+ dynamic_1D(const dynamic_1D& other)
+ : m_size(0), m_data(0), m_alloc()
+ {
+ this->copy(other);
+ }
+
+ ~dynamic_1D() {
+ this->destroy();
+ }
public:
/** Return the number of elements in the array. */
- size_t size() const { return this->m_data.size(); }
+ size_t size() const { return m_size; }
/** Access to the data as a C array.
*
*
* @note This function does not range-check the argument.
*/
- reference operator[](size_t i) { return this->m_data[i]; }
+ reference operator[](size_t i) { return m_data[i]; }
/** Const access to the data as a C array.
*
*
* @note This function does not range-check the argument.
*/
- const_reference operator[](size_t i) const { return this->m_data[i]; }
+ const_reference operator[](size_t i) const { return m_data[i]; }
/** Return access to the data as a raw pointer. */
pointer data() { return &m_data[0]; }
public:
- /** Set the array size to the given value.
+ /** Set the array size to the given value. The previous contents are
+ * destroyed before reallocating the array. If s == size(),
+ * nothing happens.
*
* @warning This is not guaranteed to preserve the original data.
*/
- void resize(size_t s) { this->m_data.resize(s); }
+ void resize(size_t s) {
+
+ /* Nothing to do if the size isn't changing: */
+ if(s == m_size) return;
+
+ /* Destroy the current array contents: */
+ this->destroy();
+
+ /* Set the new size if non-zero: */
+ if(s > 0) {
+ value_type* data = m_alloc.allocate(s);
+ for(size_t i = 0; i < s; ++ i)
+ m_alloc.construct(&data[i], value_type());
+
+ /* Success, save s and data: */
+ m_size = s;
+ m_data = data;
+ }
+ }
+
+ /** Copy the source array. The previous contents are destroyed before
+ * reallocating the array. If other == *this, nothing happens.
+ */
+ void copy(const dynamic_1D& other) {
+
+ /* Nothing to do if it's the same array: */
+ if(&other == this) return;
+
+ /* Destroy the current array contents: */
+ this->destroy();
+
+ /* Set the new size if non-zero: */
+ size_t s = other.size();
+ if(s > 0) {
+ value_type* data = m_alloc.allocate(s);
+ for(size_t i = 0; i < s; ++ i)
+ m_alloc.construct(&data[i], other[i]);
+
+ /* Success, so save the new array and the size: */
+ m_size = s;
+ m_data = data;
+ }
+ }
protected:
- array_impl m_data;
+ /** Destroy the current contents of the array. */
+ void destroy() {
+ if(m_data) {
+ for(size_t i = 0; i < m_size; ++ i)
+ m_alloc.destroy(&m_data[i]);
+ m_alloc.deallocate(m_data, m_size);
+ m_size = 0;
+ m_data = 0;
+ }
+ }
+
+
+ protected:
+
+ /** Current array size (may be 0). */
+ size_t m_size;
+
+ /** Array data (may be NULL). */
+ value_type* m_data;
+
+ /** Allocator for the array. */
+ allocator_type m_alloc;
};
} // namespace cml
#ifndef dynamic_2D_h
#define dynamic_2D_h
-#include <vector>
+#include <memory>
#include <cml/core/common.h>
#include <cml/core/dynamic_1D.h>
#include <cml/dynamic.h>
/* Record the generator: */
typedef dynamic<Alloc> generator_type;
- /* Array implementation: */
- typedef std::vector<Element,allocator_type> array_impl;
-
/* Standard: */
- typedef typename array_impl::value_type value_type;
- typedef typename array_impl::pointer pointer;
- typedef typename array_impl::reference reference;
- typedef typename array_impl::const_reference const_reference;
- typedef typename array_impl::const_pointer const_pointer;
+ typedef typename allocator_type::value_type value_type;
+ typedef typename allocator_type::pointer pointer;
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+ typedef typename allocator_type::const_pointer const_pointer;
/* For matching by memory layout: */
typedef Layout layout;
typedef twod_tag dimension_tag;
/* To simplify the matrix transpose operator: */
- typedef dynamic_2D<Element,Layout,Alloc> transposed_type;
+ typedef dynamic_2D<typename cml::remove_const<Element>::type,
+ Layout,Alloc> transposed_type;
/* To simplify the matrix row and column operators: */
typedef dynamic_1D<Element,Alloc> row_array_type;
protected:
/** Construct a dynamic array with no size. */
- dynamic_2D() {}
+ dynamic_2D() : m_rows(0), m_cols(0), m_data(0), m_alloc() {}
- /** Construct a dynamic matrix given the dimensions.
- *
- * This constructor is guaranteed to throw only if the allocator throws.
- * If the array implementation guarantees that the array data structure is
- * not modified after an exception, then this constructor is
- * exception-safe.
- *
- * @throws only if the allocator throws during an allocation.
- */
+ /** Construct a dynamic matrix given the dimensions. */
explicit dynamic_2D(size_t rows, size_t cols)
- : m_rows(rows), m_cols(cols), m_data(rows*cols) {}
+ : m_rows(0), m_cols(0), m_data(0), m_alloc()
+ {
+ this->resize(rows, cols);
+ }
+
+ /** Copy construct a dynamic matrix. */
+ dynamic_2D(const dynamic_2D& other)
+ : m_rows(0), m_cols(0), m_data(0), m_alloc()
+ {
+ this->copy(other);
+ }
+
+ ~dynamic_2D() {
+ this->destroy();
+ }
public:
* @returns mutable reference.
*/
reference operator()(size_t row, size_t col) {
- return get_element(row, col, layout());
+ return this->get_element(row, col, layout());
}
/** Access the given element of the matrix.
* @returns const reference.
*/
const_reference operator()(size_t row, size_t col) const {
- return get_element(row, col, layout());
+ return this->get_element(row, col, layout());
}
/** Return access to the data as a raw pointer. */
public:
- /** Resize the array.
+ /** Set the array dimensions. The previous contents are destroyed
+ * before reallocating the array. If the number of rows and columns
+ * isn't changing, nothing happens. Also, if either rows or cols is 0,
+ * the array is cleared.
*
* @warning This is not guaranteed to preserve the original data.
*/
void resize(size_t rows, size_t cols) {
- m_data.resize(rows*cols); m_rows = rows; m_cols = cols;
+
+ /* Nothing to do if the size isn't changing: */
+ if(rows == m_rows && cols == m_cols) return;
+
+ /* Destroy the current array contents: */
+ this->destroy();
+
+ /* Set the new size if non-zero: */
+ if(rows*cols > 0) {
+ value_type* data = m_alloc.allocate(rows*cols);
+ for(size_t i = 0; i < rows*cols; ++ i)
+ m_alloc.construct(&data[i], value_type());
+
+ /* Success, so save the new array and the dimensions: */
+ m_rows = rows;
+ m_cols = cols;
+ m_data = data;
+ }
+ }
+
+ /** Copy the other array. The previous contents are destroyed before
+ * reallocating the array. If other == *this, nothing happens. Also,
+ * if either other.rows() or other.cols() is 0, the array is cleared.
+ */
+ void copy(const dynamic_2D& other) {
+
+ /* Nothing to do if it's the same array: */
+ if(&other == this) return;
+
+ /* Destroy the current array contents: */
+ this->destroy();
+
+ /* Set the new size if non-zero: */
+ size_t rows = other.rows(), cols = other.cols();
+ if(rows*cols > 0) {
+ value_type* data = m_alloc.allocate(rows*cols);
+ for(size_t i = 0; i < rows*cols; ++ i)
+ m_alloc.construct(&data[i], other[i]);
+
+ /* Success, so save the new array and the dimensions: */
+ m_rows = rows;
+ m_cols = cols;
+ m_data = data;
+ }
}
protected:
+ /** Destroy the current contents of the array. */
+ void destroy() {
+ if(m_data) {
+ for(size_t i = 0; i < m_rows*m_cols; ++ i)
+ m_alloc.destroy(&m_data[i]);
+ m_alloc.deallocate(m_data, m_rows*m_cols);
+ m_rows = m_cols = 0;
+ m_data = 0;
+ }
+ }
+
+
+ protected:
+
+ /** Current array dimensions (may be 0,0). */
size_t m_rows, m_cols;
- array_impl m_data;
+
+ /** Array data (may be NULL). */
+ value_type* m_data;
+
+ /** Allocator for the array. */
+ allocator_type m_alloc;
};
} // namespace cml
typedef twod_tag dimension_tag;
/* To simplify the matrix transpose operator: */
- typedef fixed_2D<Element,Cols,Rows,Layout> transposed_type;
+ typedef fixed_2D<typename cml::remove_const<Element>::type,
+ Cols,Rows,Layout> transposed_type;
/* Note: the transposed type must be fixed_2D, since an external array
* cannot be specified without a corresponding memory location.
*/
typedef twod_tag dimension_tag;
/* To simplify the matrix transpose operator: */
- typedef dynamic_2D<Element,Layout, CML_DEFAULT_ARRAY_ALLOC>
- transposed_type;
+ typedef dynamic_2D<typename cml::remove_const<Element>::type,
+ Layout, CML_DEFAULT_ARRAY_ALLOC> transposed_type;
/* To simplify the matrix row and column operators: */
typedef dynamic_1D<Element, CML_DEFAULT_ARRAY_ALLOC> row_array_type;
typedef twod_tag dimension_tag;
/* To simplify the matrix transpose operator: */
- typedef fixed_2D<Element,Cols,Rows,Layout> transposed_type;
+ typedef fixed_2D<typename cml::remove_const<Element>::type,
+ Cols,Rows,Layout> transposed_type;
/* To simplify the matrix row and column operators: */
typedef fixed_1D<Element,Rows> row_array_type;
, typename T14 = NilCase, typename R14 = void
, typename T15 = NilCase, typename R15 = void
, typename T16 = NilCase, typename R16 = void
-#if !defined(_MSC_VER)
-, typename T17 = NilCase, typename R17 = void
-, typename T18 = NilCase, typename R18 = void
-, typename T19 = NilCase, typename R19 = void
-, typename T20 = NilCase, typename R20 = void
-, typename T21 = NilCase, typename R21 = void
-, typename T22 = NilCase, typename R22 = void
-, typename T23 = NilCase, typename R23 = void
-, typename T24 = NilCase, typename R24 = void
-, typename T25 = NilCase, typename R25 = void
-, typename T26 = NilCase, typename R26 = void
-, typename T27 = NilCase, typename R27 = void
-, typename T28 = NilCase, typename R28 = void
-, typename T29 = NilCase, typename R29 = void
-, typename T30 = NilCase, typename R30 = void
-, typename T31 = NilCase, typename R31 = void
-, typename T32 = NilCase, typename R32 = void
-, typename T33 = NilCase, typename R33 = void
-, typename T34 = NilCase, typename R34 = void
-, typename T35 = NilCase, typename R35 = void
-, typename T36 = NilCase, typename R36 = void
-, typename T37 = NilCase, typename R37 = void
-, typename T38 = NilCase, typename R38 = void
-, typename T39 = NilCase, typename R39 = void
-, typename T40 = NilCase, typename R40 = void
-#endif
> struct select_switch
{
typedef typename
, meta::select_case< T14,R14
, meta::select_case< T15,R15
, meta::select_case< T16,R16
-#if !defined(_MSC_VER)
- , meta::select_case< T17,R17
- , meta::select_case< T18,R18
- , meta::select_case< T19,R19
- , meta::select_case< T20,R20
- , meta::select_case< T21,R21
- , meta::select_case< T22,R22
- , meta::select_case< T23,R23
- , meta::select_case< T24,R24
- , meta::select_case< T25,R25
- , meta::select_case< T26,R26
- , meta::select_case< T27,R27
- , meta::select_case< T28,R28
- , meta::select_case< T29,R29
- , meta::select_case< T30,R30
- , meta::select_case< T31,R31
- , meta::select_case< T32,R32
- , meta::select_case< T33,R33
- , meta::select_case< T34,R34
- , meta::select_case< T35,R35
- , meta::select_case< T36,R36
- , meta::select_case< T37,R37
- , meta::select_case< T38,R38
- , meta::select_case< T39,R39
- , meta::select_case< T40,R40
, NilCase
- > > > > > > > > > > /* 10 */
- > > > > > > > > > > /* 10 */
- > > > > /* 4 */
-#else
- , NilCase
-#endif
> > > > > > /* 6 */
> > > > > > > > > > /* 10 */
::template match<Find>::result result;
namespace cml {
namespace et {
-// #define CML_USE_OLD_SCALAR_PROMOTIONS
-#if !defined(CML_USE_OLD_SCALAR_PROMOTIONS)
-
/* The type promotion code below is a slightly modified version of:
* http://ubiety.uwaterloo.ca/~tveldhui/papers/techniques/techniques01.html
*/
template<class T1_orig, class T2_orig>
struct promote_trait {
+
+ // Need to remove const-ness:
+ typedef typename cml::remove_const<T1_orig>::type T1_non_const;
+ typedef typename cml::remove_const<T2_orig>::type T2_non_const;
+
// Handle promotion of small integers to int/unsigned int
- typedef typename autopromote_trait<T1_orig>::T_numtype T1;
- typedef typename autopromote_trait<T2_orig>::T_numtype T2;
+ typedef typename autopromote_trait<T1_non_const>::T_numtype T1;
+ typedef typename autopromote_trait<T2_non_const>::T_numtype T2;
// True if T1 is higher ranked
enum {
typedef typename detail::promote_trait<E1,E2>::T_promote type;
};
-#else
-
-namespace detail {
-
-/** @class IntPromote
- * @brief Helper template to int-promote a type.
- */
-template<class T> struct IntPromote
-{
- /* Signed -> signed int, unsigned -> unsigned int: */
- typedef typename select_switch<T,
- unsigned char, unsigned int,
- unsigned short, unsigned int,
- signed char, int,
- char, int,
- short, int,
- T, T
- >::result result;
-};
-
-} // namespace detail
-
-/** @class ScalarPromote
- * @brief Template for compile-time type promotion via C promotion rules.
- */
-template<class E1_in, class E2_in> struct ScalarPromote
-{
- /* Integral-promote the types (if possible). */
- typedef typename detail::IntPromote<E1_in>::result E1;
- typedef typename detail::IntPromote<E2_in>::result E2;
-
- /* If sizeof(long) == sizeof(unsigned int), promote to unsigned long.
- * Otherwise, sizeof(long) > sizeof(int), so promote to long.
- */
- typedef typename select_if<sizeof(long) == sizeof(unsigned int),
- unsigned long,
- long
- >::result uint_promotion;
-
- /* Do the selection on the promoted types: */
- typedef typename select_switch<
- type_pair<E1,E2>,
-
-#if defined(CML_USE_LONG_DOUBLE)
- type_pair<long double,long double>, long double,
- type_pair<long double,E2>, long double,
- type_pair<E1,long double>, long double,
-#endif
-
- type_pair<double,double>, double,
- type_pair<double,E2>, double,
- type_pair<E1,double>, double,
-
- type_pair<float,float>, float,
- type_pair<float,E2>, float,
- type_pair<E1,float>, float,
-
- type_pair<E1,E2>, void
-
- >::result float_filter;
-
- /* The promoted integral types really matter here: */
- typedef typename select_switch<
- type_pair<E1,E2>,
-
- type_pair<unsigned long,unsigned long>, unsigned long,
- type_pair<unsigned long,E2>, unsigned long,
- type_pair<E1,unsigned long>, unsigned long,
-
- type_pair<long,long>, long,
- type_pair<long,unsigned int>, uint_promotion,
- type_pair<unsigned int,long>, uint_promotion,
-
- type_pair<long,E2>, long,
- type_pair<E1,long>, long,
-
- type_pair<unsigned int,unsigned int>, unsigned int,
- type_pair<unsigned int,E2>, unsigned int,
- type_pair<E1,unsigned int>, unsigned int,
-
- type_pair<int,int>, int,
- type_pair<int,E2>, int,
- type_pair<E1,int>, int,
-
- type_pair<E1,E2>, void
-
- >::result int_filter;
-
- /* Deduce the final type: */
- typedef typename select_if<
- same_type<float_filter,void>::is_true,
- int_filter, float_filter>::result type;
-};
-#endif
-
} // namespace et
} // namespace cml
temporary_type result;
detail::InterpResize(result, val1, size_tag());
- result = val0 * (Scalar(1) - u) + val1 * u;
+ result = (Scalar(1) - u) * val0 + u * val1;
return result;
}
/* Checking */
detail::CheckMatLinear3D(m);
- identity_transform(m);
-
size_t i, j, k;
bool odd, repeat;
detail::unpack_euler_order(order, i, j, k, odd, repeat);
}
}
+/** Convenience function to return a 3D vector containing the Euler angles
+ * in the requested order.
+ */
+template < class MatT, typename Real > vector< Real, fixed<3> >
+matrix_to_euler(
+ const MatT& m,
+ EulerOrder order,
+ Real tolerance = epsilon<Real>::placeholder())
+{
+ Real e0, e1, e2;
+ matrix_to_euler(m, e0, e1, e2, order, tolerance);
+ return vector< Real, fixed<3> >(e0, e1, e2);
+}
+
/** Convert a 2D rotation matrix to a rotation angle */
template < class MatT > typename MatT::value_type
matrix_to_rotation_2D(const MatT& m)
/* To simplify the matrix transpose operator: */
typedef matrix<
- Element,
+ typename cml::remove_const<Element>::type,
typename array_type::transposed_type::generator_type,
BasisOrient,
Layout
/* To simplify the matrix transpose operator: */
typedef matrix<
- Element,
+ typename cml::remove_const<Element>::type,
typename array_type::transposed_type::generator_type,
- BasisOrient,
- Layout
+ BasisOrient, Layout
> transposed_type;
/* To simplify the matrix row and column operators: */
#ifndef matrix_inverse_h
#define matrix_inverse_h
+#include <vector>
#include <cml/matrix/lu.h>
namespace cml {
#include <cml/quaternion/quaternion_functions.h>
#include <cml/quaternion/quaternion_comparison.h>
#include <cml/quaternion/inverse.h>
-#include <cml/quaternion/quaternion_print.h>
-
#include <cml/quaternion/quaternion.h>
-
+#include <cml/quaternion/quaternion_print.h>
#endif
// -------------------------------------------------------------------------
template<typename E, class AT, class OT, typename CT> std::ostream&
operator<<(std::ostream& os, const cml::quaternion<E,AT,OT,CT>& q)
{
- os << "[";
- for (size_t i = 0; i < 4; ++i) {
- os << " " << q[i];
- }
- os << " ]";
+ typedef typename cml::quaternion<E,AT,OT,CT>::order_type order_type;
+ enum {
+ W = order_type::W,
+ X = order_type::X,
+ Y = order_type::Y,
+ Z = order_type::Z
+ };
+
+ os << "[ "
+ << " " << q[W]
+ << " " << q[X]
+ << " " << q[Y]
+ << " " << q[Z]
+ << " ]";
+
return os;
}
typedef vector_type expr_type;
/* For integration into the expression template code: */
- typedef vector< Element,fixed<Size> > temporary_type;
+ typedef vector<typename cml::remove_const<Element>::type,
+ fixed<Size> > temporary_type;
typedef typename temporary_type::subvector_type subvector_type;
/* Note: this ensures that an external vector is copied into the proper
* temporary; external<> temporaries are not allowed.
typedef vector_type expr_type;
/* For integration into the expression template code: */
- typedef vector< Element, dynamic<> > temporary_type;
+ typedef vector<typename cml::remove_const<Element>::type,
+ dynamic<> > temporary_type;
/* Note: this ensures that an external vector is copied into the proper
* temporary; external<> temporaries are not allowed.
*/
+++ /dev/null
-
-Parts of STLplus C++ Library Collection
-http://stlplus.sourceforge.net/
-
-© 1999-2004 Southampton University, 2004-2009 Andy Rushton. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above Copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above Copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the STLplus library nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-This software is provided by the Copyright holders and contributors "as is" and
-any express or implied warranties, including, but not limited to, the implied
-warranties of merchantability and fitness for a particular purpose are
-disclaimed. In no event shall the Copyright owner or contributors be liable for
-any direct, indirect, incidental, special, exemplary, or consequential damages
-(including, but not limited to, procurement of substitute goods or services;
-loss of use, data, or profits; or business interruption) however caused and on
-any theory of liability, whether in contract, strict liability, or tort
-(including negligence or otherwise) arising in any way out of the use of this
-software, even if advised of the possibility of such damage.
-