Files
triton/atidlas/expression_template.hpp

81 lines
2.5 KiB
C++
Raw Normal View History

2014-11-09 16:29:55 -05:00
#ifndef ATIDLAS_EXPRESSION_TEMPLATE_HPP_
#define ATIDLAS_EXPRESSION_TEMPLATE_HPP_
#include "atidlas/forwards.h"
#include "atidlas/traits/size.hpp"
namespace atidlas
{
namespace detail
{
template<typename T>
struct reference_if_nonscalar
{
typedef T & type;
};
#define ATIDLAS_REFERENCE_IF_NONSCALAR(TNAME) \
template<> struct reference_if_nonscalar<TNAME> { typedef TNAME type; }; \
template<> struct reference_if_nonscalar<const TNAME> { typedef const TNAME type; };
ATIDLAS_REFERENCE_IF_NONSCALAR(char)
ATIDLAS_REFERENCE_IF_NONSCALAR(short)
ATIDLAS_REFERENCE_IF_NONSCALAR(int)
ATIDLAS_REFERENCE_IF_NONSCALAR(long)
ATIDLAS_REFERENCE_IF_NONSCALAR(unsigned char)
ATIDLAS_REFERENCE_IF_NONSCALAR(unsigned short)
ATIDLAS_REFERENCE_IF_NONSCALAR(unsigned int)
ATIDLAS_REFERENCE_IF_NONSCALAR(unsigned long)
ATIDLAS_REFERENCE_IF_NONSCALAR(float)
ATIDLAS_REFERENCE_IF_NONSCALAR(double)
#undef ATIDLAS_REFERENCE_IF_NONSCALAR
}
/** @brief An expression template class that represents a binary operation
* @tparam LHS left hand side operand
* @tparam RHS right hand side operand
* @tparam OP the operator
*/
template<typename LHS, typename RHS, typename OP>
class expression_template
{
typedef typename detail::reference_if_nonscalar<LHS>::type lhs_reference_type;
typedef typename detail::reference_if_nonscalar<RHS>::type rhs_reference_type;
public:
expression_template(LHS & l, RHS & r) : lhs_(l), rhs_(r) {}
/** @brief Get left hand side operand */
lhs_reference_type lhs() const { return lhs_; }
/** @brief Get right hand side operand */
rhs_reference_type rhs() const { return rhs_; }
/** @brief Returns the size of the result vector */
atidlas_int_t size() const { return traits::size(*this); }
private:
/** @brief The left hand side operand */
lhs_reference_type lhs_;
/** @brief The right hand side operand */
rhs_reference_type rhs_;
};
template<typename LHS, typename RHS, typename OP>
struct vector_expression: public expression_template<LHS, RHS, OP>{
vector_expression(LHS & l, RHS & r) : expression_template<LHS, RHS, OP>(l, r){ }
};
template<typename LHS, typename RHS, typename OP>
class matrix_expression: public expression_template<LHS, RHS, OP>{
matrix_expression(LHS & l, RHS & r) : expression_template<LHS, RHS, OP>(l, r){ }
};
template<typename LHS, typename RHS, typename OP>
class scalar_expression: public expression_template<LHS, RHS, OP>{
scalar_expression(LHS & l, RHS & r) : expression_template<LHS, RHS, OP>(l, r){ }
};
}
#endif