X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fcml%2Fvector%2Fclass_ops.h;fp=src%2Fcml%2Fvector%2Fclass_ops.h;h=0b7a36115b9dd0608076aef449777c51f3d23108;hp=0000000000000000000000000000000000000000;hb=6b0a0d0efafe34d48ab344fca3b479553bd4e62c;hpb=85783316365181491a3e3c0c63659972477cebba diff --git a/src/cml/vector/class_ops.h b/src/cml/vector/class_ops.h new file mode 100644 index 0000000..0b7a361 --- /dev/null +++ b/src/cml/vector/class_ops.h @@ -0,0 +1,238 @@ +/* -*- C++ -*- ------------------------------------------------------------ + +Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/ + +The Configurable Math Library (CML) is distributed under the terms of the +Boost Software License, v1.0 (see cml/LICENSE for details). + + *-----------------------------------------------------------------------*/ +/** @file + * @brief Vector class operators. + */ + +#ifndef vector_class_ops_h +#define vector_class_ops_h + +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma warning(disable:4003) +// XXX Horrible hack to turn off warnings about "not enough actual params" +// for the macros below. +#endif + +/* XXX HACK!!! This is a hack to resize in the assign() functions only when + * auto resizing is turned off. + */ +#if !defined(CML_VECTOR_RESIZE_ON_ASSIGNMENT) +#define _DO_VECTOR_SET_RESIZE(_N_) cml::et::detail::Resize(*this,_N_) +#else +#define _DO_VECTOR_SET_RESIZE(_N_) +#endif + +/** Set a vector from 2 values. */ +#define CML_ASSIGN_VEC_2 \ +vector_type& \ +set(ELEMENT_ARG_TYPE e0, ELEMENT_ARG_TYPE e1) { \ + _DO_VECTOR_SET_RESIZE(2); \ + /* This is overkill, but simplifies size checking: */ \ + value_type v[] = {e0,e1}; \ + typedef et::OpAssign OpT; \ + cml::vector< const value_type, external<2> > src(v); \ + et::UnrollAssignment(*this,src); \ + return *this; \ +} + +/** Set a vector from 3 values. */ +#define CML_ASSIGN_VEC_3 \ +vector_type& \ +set( \ + ELEMENT_ARG_TYPE e0, \ + ELEMENT_ARG_TYPE e1, \ + ELEMENT_ARG_TYPE e2 \ + ) \ +{ \ + _DO_VECTOR_SET_RESIZE(3); \ + /* This is overkill, but simplifies size checking: */ \ + value_type v[] = {e0,e1,e2}; \ + typedef et::OpAssign OpT; \ + cml::vector< const value_type, external<3> > src(v); \ + et::UnrollAssignment(*this,src); \ + return *this; \ +} + +/** Create a vector from 4 values. */ +#define CML_ASSIGN_VEC_4 \ +vector_type& \ +set( \ + ELEMENT_ARG_TYPE e0, \ + ELEMENT_ARG_TYPE e1, \ + ELEMENT_ARG_TYPE e2, \ + ELEMENT_ARG_TYPE e3 \ + ) \ +{ \ + _DO_VECTOR_SET_RESIZE(4); \ + /* This is overkill, but simplifies size checking: */ \ + value_type v[] = {e0,e1,e2,e3}; \ + typedef et::OpAssign OpT; \ + cml::vector< const value_type, external<4> > src(v); \ + et::UnrollAssignment(*this,src); \ + return *this; \ +} + + +/** Create a vector from 2 values. */ +#define CML_CONSTRUCT_VEC_2(_add_) \ +vector(ELEMENT_ARG_TYPE e0, ELEMENT_ARG_TYPE e1) _add_ { \ + set(e0,e1); \ +} + +/** Create a vector from 3 values. */ +#define CML_CONSTRUCT_VEC_3(_add_) \ +vector( \ + ELEMENT_ARG_TYPE e0, \ + ELEMENT_ARG_TYPE e1, \ + ELEMENT_ARG_TYPE e2 \ + ) _add_ \ +{ \ + set(e0,e1,e2); \ +} + +/** Create a vector from 4 values. */ +#define CML_CONSTRUCT_VEC_4(_add_) \ +vector( \ + ELEMENT_ARG_TYPE e0, \ + ELEMENT_ARG_TYPE e1, \ + ELEMENT_ARG_TYPE e2, \ + ELEMENT_ARG_TYPE e3 \ + ) _add_ \ +{ \ + set(e0,e1,e2,e3); \ +} + +/** Create a (fixed-size) N vector from an N-1-vector and a scalar. */ +#define CML_CONSTRUCT_FROM_SUBVEC(_add_) \ +vector( \ + const subvector_type& s, \ + ELEMENT_ARG_TYPE e \ + ) _add_ \ +{ \ + _DO_VECTOR_SET_RESIZE(s.size()+1); \ + for(size_t i = 0; i < s.size(); ++ i) \ + (*this)[i] = s[i]; \ + (*this)[s.size()] = e; \ +} + +/** Copy-construct a vector from a fixed-size array of values. */ +#define CML_VEC_COPY_FROM_FIXED_ARRAY(_N_,_add_) \ +vector(const value_type v[_N_]) _add_ { \ + typedef et::OpAssign OpT; \ + cml::vector< const value_type, external<_N_> > src(v); \ + et::UnrollAssignment(*this,src); \ +} + +/** Copy-construct a vector from a runtime-sized array of values. */ +#define CML_VEC_COPY_FROM_ARRAY(_add_) \ +vector(const value_type* const v, size_t N) _add_ { \ + typedef et::OpAssign OpT; \ + cml::vector > src(v,N); \ + et::UnrollAssignment(*this,src); \ +} + +/** Copy-construct a vector. + * + * @internal This is required for GCC4, since it won't elide the default + * copy constructor. + */ +#define CML_VEC_COPY_FROM_VECTYPE(_add_) \ +vector(const vector_type& v) _add_ { \ + typedef et::OpAssign OpT; \ + et::UnrollAssignment(*this,v); \ +} + +/** Construct from an arbitrary vector. + * + * @param v the vector to copy from. + */ +#define CML_VEC_COPY_FROM_VEC \ +template \ +vector(const vector& m) { \ + typedef et::OpAssign OpT; \ + et::UnrollAssignment(*this,m); \ +} + +/** Construct from a vector expression. + * + * @param expr the expression to copy from. + */ +#define CML_VEC_COPY_FROM_VECXPR \ +template \ +vector(VECXPR_ARG_TYPE e) { \ + /* Verify that a promotion exists at compile time: */ \ + typedef typename et::VectorPromote< \ + vector_type, typename XprT::result_type>::type result_type; \ + typedef typename XprT::value_type src_value_type; \ + typedef et::OpAssign OpT; \ + et::UnrollAssignment(*this,e); \ +} + +/** Assign from the same vector type. + * + * @param v the vector to copy from. + */ +#define CML_VEC_ASSIGN_FROM_VECTYPE \ +vector_type& operator=(const vector_type& v) { \ + typedef et::OpAssign OpT; \ + et::UnrollAssignment(*this,v); \ + return *this; \ +} + +/** Assign this vector from another using the given elementwise op. + * + * This allows assignment from arbitrary vector types. + * + * @param _op_ the operator (e.g. +=) + * @param _op_name_ the op functor (e.g. et::OpAssign) + */ +#define CML_VEC_ASSIGN_FROM_VEC(_op_, _op_name_) \ +template vector_type& \ +operator _op_ (const cml::vector& m) { \ + typedef _op_name_ OpT; \ + cml::et::UnrollAssignment(*this,m); \ + return *this; \ +} + +/** Declare a function to assign this vector from a vector expression. + * + * @param _op_ the operator (e.g. +=) + * @param _op_name_ the op functor (e.g. et::OpAssign) + */ +#define CML_VEC_ASSIGN_FROM_VECXPR(_op_, _op_name_) \ +template vector_type& \ +operator _op_ (VECXPR_ARG_TYPE e) { \ + /* Verify that a promotion exists at compile time: */ \ + typedef typename et::VectorPromote< \ + vector_type, typename XprT::result_type>::type result_type; \ + typedef typename XprT::value_type src_value_type; \ + typedef _op_name_ OpT; \ + cml::et::UnrollAssignment(*this,e); \ + return *this; \ +} + +/** Declare a function to assign this vector from a scalar. + * + * @param _op_ the operator (e.g. *=) + * @param _op_name_ the op functor (e.g. et::OpAssign) + * + * @internal This shouldn't be used for ops, like +=, which aren't + * defined in vector algebra. + */ +#define CML_VEC_ASSIGN_FROM_SCALAR(_op_, _op_name_) \ +vector_type& operator _op_ (ELEMENT_ARG_TYPE s) { \ + typedef _op_name_ OpT; \ + cml::et::UnrollAssignment(*this,s); \ + return *this; \ +} + +#endif + +// ------------------------------------------------------------------------- +// vim:ft=cpp