Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58515 - in sandbox/numeric_bindings/boost/numeric/bindings/blas: detail level1 level2 level3
From: rutger_at_[hidden]
Date: 2009-12-23 10:12:41


Author: rutger
Date: 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
New Revision: 58515
URL: http://svn.boost.org/trac/boost/changeset/58515

Log:
Sync of latest BLAS bindings, using new traits system

Added:
   sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/default_order.hpp (contents, props changed)
Text files modified:
   sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas.h | 773 ++++++++++++++++++++-------------------
   sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas_names.h | 2
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/asum.hpp | 149 ++++++-
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/axpy.hpp | 278 +++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/copy.hpp | 266 ++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dot.hpp | 164 ++++++-
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotc.hpp | 173 ++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotu.hpp | 176 ++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/drot.hpp | 21
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/nrm2.hpp | 149 ++++++-
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rot.hpp | 187 +++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotg.hpp | 417 +++++++++++++++++++-
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotm.hpp | 288 ++++++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotmg.hpp | 525 +++++++++++++++++++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/scal.hpp | 251 ++++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/sdot.hpp | 132 +++++-
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/swap.hpp | 287 +++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gbmv.hpp | 374 ++++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gemv.hpp | 361 +++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/ger.hpp | 207 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gerc.hpp | 224 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/geru.hpp | 224 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hbmv.hpp | 240 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hemv.hpp | 236 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her.hpp | 200 +++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her2.hpp | 229 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpmv.hpp | 238 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr.hpp | 200 +++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr2.hpp | 222 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/sbmv.hpp | 222 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spmv.hpp | 214 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr.hpp | 185 +++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr2.hpp | 207 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/symv.hpp | 220 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr.hpp | 194 +++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr2.hpp | 208 ++++++++--
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbmv.hpp | 323 ++++++++++++----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbsv.hpp | 323 ++++++++++++----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpmv.hpp | 308 +++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpsv.hpp | 308 +++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trmv.hpp | 309 ++++++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trsv.hpp | 316 ++++++++++++----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/gemm.hpp | 390 ++++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/hemm.hpp | 253 +++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/her2k.hpp | 253 +++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/herk.hpp | 234 ++++++++---
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/symm.hpp | 365 +++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syr2k.hpp | 372 +++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syrk.hpp | 354 +++++++++++++----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trmm.hpp | 363 +++++++++++++-----
   sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trsm.hpp | 368 +++++++++++++-----
   51 files changed, 10036 insertions(+), 3446 deletions(-)

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas.h
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas.h (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas.h 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,7 +14,6 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_DETAIL_BLAS_H
 #define BOOST_NUMERIC_BINDINGS_BLAS_DETAIL_BLAS_H
 
-#include <boost/numeric/bindings/traits/type.h>
 #include <boost/numeric/bindings/blas/detail/blas_names.h>
 
 extern "C" {
@@ -24,68 +23,80 @@
 //
 
 // Value-type variants of asum
-float BLAS_SASUM( const integer_t* n, const float* x, const integer_t* incx );
-double BLAS_DASUM( const integer_t* n, const double* x,
- const integer_t* incx );
+float BLAS_SASUM( const std::ptrdiff_t* n, const float* x,
+ const std::ptrdiff_t* incx );
+double BLAS_DASUM( const std::ptrdiff_t* n, const double* x,
+ const std::ptrdiff_t* incx );
 
 // Value-type variants of axpy
-void BLAS_SAXPY( const integer_t* n, const float* a, const float* x,
- const integer_t* incx, float* y, const integer_t* incy );
-void BLAS_DAXPY( const integer_t* n, const double* a, const double* x,
- const integer_t* incx, double* y, const integer_t* incy );
-void BLAS_CAXPY( const integer_t* n, const fcomplex_t* a, const fcomplex_t* x,
- const integer_t* incx, fcomplex_t* y, const integer_t* incy );
-void BLAS_ZAXPY( const integer_t* n, const dcomplex_t* a, const dcomplex_t* x,
- const integer_t* incx, dcomplex_t* y, const integer_t* incy );
+void BLAS_SAXPY( const std::ptrdiff_t* n, const float* a, const float* x,
+ const std::ptrdiff_t* incx, float* y, const std::ptrdiff_t* incy );
+void BLAS_DAXPY( const std::ptrdiff_t* n, const double* a, const double* x,
+ const std::ptrdiff_t* incx, double* y, const std::ptrdiff_t* incy );
+void BLAS_CAXPY( const std::ptrdiff_t* n, const void* a, const void* x,
+ const std::ptrdiff_t* incx, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZAXPY( const std::ptrdiff_t* n, const void* a, const void* x,
+ const std::ptrdiff_t* incx, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of copy
-void BLAS_SCOPY( const integer_t* n, const float* x, const integer_t* incx,
- const float* y, const integer_t* incy );
-void BLAS_DCOPY( const integer_t* n, const double* x, const integer_t* incx,
- const double* y, const integer_t* incy );
-void BLAS_CCOPY( const integer_t* n, const fcomplex_t* x,
- const integer_t* incx, const fcomplex_t* y, const integer_t* incy );
-void BLAS_ZCOPY( const integer_t* n, const dcomplex_t* x,
- const integer_t* incx, const dcomplex_t* y, const integer_t* incy );
+void BLAS_SCOPY( const std::ptrdiff_t* n, const float* x,
+ const std::ptrdiff_t* incx, float* y, const std::ptrdiff_t* incy );
+void BLAS_DCOPY( const std::ptrdiff_t* n, const double* x,
+ const std::ptrdiff_t* incx, double* y, const std::ptrdiff_t* incy );
+void BLAS_CCOPY( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZCOPY( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of dot
-float BLAS_SDOT( const integer_t* n, const float* x, const integer_t* incx,
- const float* y, const integer_t* incy );
-double BLAS_DDOT( const integer_t* n, const double* x, const integer_t* incx,
- const double* y, const integer_t* incy );
+float BLAS_SDOT( const std::ptrdiff_t* n, const float* x,
+ const std::ptrdiff_t* incx, const float* y,
+ const std::ptrdiff_t* incy );
+double BLAS_DDOT( const std::ptrdiff_t* n, const double* x,
+ const std::ptrdiff_t* incx, const double* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of dotc
-fcomplex_t BLAS_CDOTC( const integer_t* n, const fcomplex_t* x,
- const integer_t* incx, const fcomplex_t* y, const integer_t* incy );
-dcomplex_t BLAS_ZDOTC( const integer_t* n, const dcomplex_t* x,
- const integer_t* incx, const dcomplex_t* y, const integer_t* incy );
+void BLAS_CDOTC( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy );
+void BLAS_ZDOTC( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of dotu
-fcomplex_t BLAS_CDOTU( const integer_t* n, const fcomplex_t* x,
- const integer_t* incx, const fcomplex_t* y, const integer_t* incy );
-dcomplex_t BLAS_ZDOTU( const integer_t* n, const dcomplex_t* x,
- const integer_t* incx, const dcomplex_t* y, const integer_t* incy );
+void BLAS_CDOTU( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy );
+void BLAS_ZDOTU( const std::ptrdiff_t* n, const void* x,
+ const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of nrm2
-float BLAS_SNRM2( const integer_t* n, const float* x, const integer_t* incx );
-double BLAS_DNRM2( const integer_t* n, const double* x,
- const integer_t* incx );
+float BLAS_SNRM2( const std::ptrdiff_t* n, const float* x,
+ const std::ptrdiff_t* incx );
+double BLAS_DNRM2( const std::ptrdiff_t* n, const double* x,
+ const std::ptrdiff_t* incx );
 
 // Value-type variants of rot
-void BLAS_SROT( const integer_t* n, const float* x, const integer_t* incx,
- float* y, const integer_t* incy, const float* c, const float* s );
-void BLAS_DROT( const integer_t* n, const double* x, const integer_t* incx,
- double* y, const integer_t* incy, const double* c, const double* s );
+void BLAS_SROT( const std::ptrdiff_t* n, const float* x,
+ const std::ptrdiff_t* incx, float* y, const std::ptrdiff_t* incy,
+ const float* c, const float* s );
+void BLAS_DROT( const std::ptrdiff_t* n, const double* x,
+ const std::ptrdiff_t* incx, double* y, const std::ptrdiff_t* incy,
+ const double* c, const double* s );
 
 // Value-type variants of rotg
 void BLAS_SROTG( float* a, float* b, float* c, float* s );
 void BLAS_DROTG( double* a, double* b, double* c, double* s );
 
 // Value-type variants of rotm
-void BLAS_SROTM( const integer_t* n, float* x, const integer_t* incx,
- float* y, const integer_t* incy, float* param );
-void BLAS_DROTM( const integer_t* n, double* x, const integer_t* incx,
- double* y, const integer_t* incy, double* param );
+void BLAS_SROTM( const std::ptrdiff_t* n, float* x,
+ const std::ptrdiff_t* incx, float* y, const std::ptrdiff_t* incy,
+ float* param );
+void BLAS_DROTM( const std::ptrdiff_t* n, double* x,
+ const std::ptrdiff_t* incx, double* y, const std::ptrdiff_t* incy,
+ double* param );
 
 // Value-type variants of rotmg
 void BLAS_SROTMG( float* d1, float* d2, float* x1, const float* y1,
@@ -94,448 +105,464 @@
         double* dparam );
 
 // Value-type variants of scal
-void BLAS_SSCAL( const integer_t* n, const float* a, const float* x,
- const integer_t* incx );
-void BLAS_DSCAL( const integer_t* n, const double* a, const double* x,
- const integer_t* incx );
-void BLAS_CSCAL( const integer_t* n, const fcomplex_t* a, const fcomplex_t* x,
- const integer_t* incx );
-void BLAS_ZSCAL( const integer_t* n, const dcomplex_t* a, const dcomplex_t* x,
- const integer_t* incx );
+void BLAS_SSCAL( const std::ptrdiff_t* n, const float* a, float* x,
+ const std::ptrdiff_t* incx );
+void BLAS_DSCAL( const std::ptrdiff_t* n, const double* a, double* x,
+ const std::ptrdiff_t* incx );
+void BLAS_CSCAL( const std::ptrdiff_t* n, const void* a, void* x,
+ const std::ptrdiff_t* incx );
+void BLAS_ZSCAL( const std::ptrdiff_t* n, const void* a, void* x,
+ const std::ptrdiff_t* incx );
 
 // Value-type variants of sdot
-double BLAS_DSDOT( const integer_t* n, const float* sx, const integer_t* incx,
- const float* sy, const integer_t* incy );
+double BLAS_DSDOT( const std::ptrdiff_t* n, const float* sx,
+ const std::ptrdiff_t* incx, const float* sy,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of swap
-void BLAS_SSWAP( const integer_t* n, float* x, const integer_t* incx,
- float* y, const integer_t* incy );
-void BLAS_DSWAP( const integer_t* n, double* x, const integer_t* incx,
- double* y, const integer_t* incy );
-void BLAS_CSWAP( const integer_t* n, fcomplex_t* x, const integer_t* incx,
- fcomplex_t* y, const integer_t* incy );
-void BLAS_ZSWAP( const integer_t* n, dcomplex_t* x, const integer_t* incx,
- dcomplex_t* y, const integer_t* incy );
+void BLAS_SSWAP( const std::ptrdiff_t* n, float* x,
+ const std::ptrdiff_t* incx, float* y, const std::ptrdiff_t* incy );
+void BLAS_DSWAP( const std::ptrdiff_t* n, double* x,
+ const std::ptrdiff_t* incx, double* y, const std::ptrdiff_t* incy );
+void BLAS_CSWAP( const std::ptrdiff_t* n, void* x, const std::ptrdiff_t* incx,
+ void* y, const std::ptrdiff_t* incy );
+void BLAS_ZSWAP( const std::ptrdiff_t* n, void* x, const std::ptrdiff_t* incx,
+ void* y, const std::ptrdiff_t* incy );
 
 //
 // BLAS level2 routines
 //
 
 // Value-type variants of gbmv
-void BLAS_SGBMV( const char* trans, const integer_t* m, const integer_t* n,
- const integer_t* kl, const integer_t* ku, const float* alpha,
- const float* a, const integer_t* lda, const float* x,
- const integer_t* incx, const float* beta, float* y,
- const integer_t* incy );
-void BLAS_DGBMV( const char* trans, const integer_t* m, const integer_t* n,
- const integer_t* kl, const integer_t* ku, const double* alpha,
- const double* a, const integer_t* lda, const double* x,
- const integer_t* incx, const double* beta, double* y,
- const integer_t* incy );
-void BLAS_CGBMV( const char* trans, const integer_t* m, const integer_t* n,
- const integer_t* kl, const integer_t* ku, const fcomplex_t* alpha,
- const fcomplex_t* a, const integer_t* lda, const fcomplex_t* x,
- const integer_t* incx, const fcomplex_t* beta, fcomplex_t* y,
- const integer_t* incy );
-void BLAS_ZGBMV( const char* trans, const integer_t* m, const integer_t* n,
- const integer_t* kl, const integer_t* ku, const dcomplex_t* alpha,
- const dcomplex_t* a, const integer_t* lda, const dcomplex_t* x,
- const integer_t* incx, const dcomplex_t* beta, dcomplex_t* y,
- const integer_t* incy );
+void BLAS_SGBMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* kl,
+ const std::ptrdiff_t* ku, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* x, const std::ptrdiff_t* incx,
+ const float* beta, float* y, const std::ptrdiff_t* incy );
+void BLAS_DGBMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* kl,
+ const std::ptrdiff_t* ku, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* x,
+ const std::ptrdiff_t* incx, const double* beta, double* y,
+ const std::ptrdiff_t* incy );
+void BLAS_CGBMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* kl,
+ const std::ptrdiff_t* ku, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZGBMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* kl,
+ const std::ptrdiff_t* ku, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of gemv
-void BLAS_SGEMV( const char* trans, const integer_t* m, const integer_t* n,
- const float* alpha, const float* a, const integer_t* lda,
- const float* x, const integer_t* incx, const float* beta, float* y,
- const integer_t* incy );
-void BLAS_DGEMV( const char* trans, const integer_t* m, const integer_t* n,
- const double* alpha, const double* a, const integer_t* lda,
- const double* x, const integer_t* incx, const double* beta, double* y,
- const integer_t* incy );
-void BLAS_CGEMV( const char* trans, const integer_t* m, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* a, const integer_t* lda,
- const fcomplex_t* x, const integer_t* incx, const fcomplex_t* beta,
- fcomplex_t* y, const integer_t* incy );
-void BLAS_ZGEMV( const char* trans, const integer_t* m, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* a, const integer_t* lda,
- const dcomplex_t* x, const integer_t* incx, const dcomplex_t* beta,
- dcomplex_t* y, const integer_t* incy );
+void BLAS_SGEMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* x, const std::ptrdiff_t* incx,
+ const float* beta, float* y, const std::ptrdiff_t* incy );
+void BLAS_DGEMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* x,
+ const std::ptrdiff_t* incx, const double* beta, double* y,
+ const std::ptrdiff_t* incy );
+void BLAS_CGEMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZGEMV( const char* trans, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of ger
-void BLAS_SGER( const integer_t* m, const integer_t* n, const float* alpha,
- const float* x, const integer_t* incx, const float* y,
- const integer_t* incy, float* a, const integer_t* lda );
-void BLAS_DGER( const integer_t* m, const integer_t* n, const double* alpha,
- const double* x, const integer_t* incx, const double* y,
- const integer_t* incy, double* a, const integer_t* lda );
+void BLAS_SGER( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const float* alpha, const float* x, const std::ptrdiff_t* incx,
+ const float* y, const std::ptrdiff_t* incy, float* a,
+ const std::ptrdiff_t* lda );
+void BLAS_DGER( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const double* alpha, const double* x, const std::ptrdiff_t* incx,
+ const double* y, const std::ptrdiff_t* incy, double* a,
+ const std::ptrdiff_t* lda );
 
 // Value-type variants of gerc
-void BLAS_CGERC( const integer_t* m, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* x, const integer_t* incx,
- const fcomplex_t* y, const integer_t* incy, fcomplex_t* a,
- const integer_t* lda );
-void BLAS_ZGERC( const integer_t* m, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* x, const integer_t* incx,
- const dcomplex_t* y, const integer_t* incy, dcomplex_t* a,
- const integer_t* lda );
+void BLAS_CGERC( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* x, const std::ptrdiff_t* incx,
+ const void* y, const std::ptrdiff_t* incy, void* a,
+ const std::ptrdiff_t* lda );
+void BLAS_ZGERC( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* x, const std::ptrdiff_t* incx,
+ const void* y, const std::ptrdiff_t* incy, void* a,
+ const std::ptrdiff_t* lda );
 
 // Value-type variants of geru
-void BLAS_CGERU( const integer_t* m, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* x, const integer_t* incx,
- const fcomplex_t* y, const integer_t* incy, fcomplex_t* a,
- const integer_t* lda );
-void BLAS_ZGERU( const integer_t* m, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* x, const integer_t* incx,
- const dcomplex_t* y, const integer_t* incy, dcomplex_t* a,
- const integer_t* lda );
+void BLAS_CGERU( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* x, const std::ptrdiff_t* incx,
+ const void* y, const std::ptrdiff_t* incy, void* a,
+ const std::ptrdiff_t* lda );
+void BLAS_ZGERU( const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* x, const std::ptrdiff_t* incx,
+ const void* y, const std::ptrdiff_t* incy, void* a,
+ const std::ptrdiff_t* lda );
 
 // Value-type variants of hbmv
-void BLAS_CHBMV( const char* uplo, const integer_t* n, const integer_t* k,
- const fcomplex_t* alpha, const fcomplex_t* a, const integer_t* lda,
- const fcomplex_t* x, const integer_t* incx, const fcomplex_t* beta,
- fcomplex_t* y, const integer_t* incy );
-void BLAS_ZHBMV( const char* uplo, const integer_t* n, const integer_t* k,
- const dcomplex_t* alpha, const dcomplex_t* a, const integer_t* lda,
- const dcomplex_t* x, const integer_t* incx, const dcomplex_t* beta,
- dcomplex_t* y, const integer_t* incy );
+void BLAS_CHBMV( const char* uplo, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZHBMV( const char* uplo, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of hemv
-void BLAS_CHEMV( const char* uplo, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* a, const integer_t* lda,
- const fcomplex_t* x, const integer_t* incx, const fcomplex_t* beta,
- fcomplex_t* y, const integer_t* incy );
-void BLAS_ZHEMV( const char* uplo, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* a, const integer_t* lda,
- const dcomplex_t* x, const integer_t* incx, const dcomplex_t* beta,
- dcomplex_t* y, const integer_t* incy );
+void BLAS_CHEMV( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* x,
+ const std::ptrdiff_t* incx, const void* beta, void* y,
+ const std::ptrdiff_t* incy );
+void BLAS_ZHEMV( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* x,
+ const std::ptrdiff_t* incx, const void* beta, void* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of her
-void BLAS_CHER( const char* uplo, const integer_t* n, const float* alpha,
- const fcomplex_t* x, const integer_t* incx, fcomplex_t* a,
- const integer_t* lda );
-void BLAS_ZHER( const char* uplo, const integer_t* n, const double* alpha,
- const dcomplex_t* x, const integer_t* incx, dcomplex_t* a,
- const integer_t* lda );
+void BLAS_CHER( const char* uplo, const std::ptrdiff_t* n, const float* alpha,
+ const void* x, const std::ptrdiff_t* incx, void* a,
+ const std::ptrdiff_t* lda );
+void BLAS_ZHER( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const void* x, const std::ptrdiff_t* incx,
+ void* a, const std::ptrdiff_t* lda );
 
 // Value-type variants of her2
-void BLAS_CHER2( const char* uplo, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* x, const integer_t* incx,
- const fcomplex_t* y, const integer_t* incy, fcomplex_t* a,
- const integer_t* lda );
-void BLAS_ZHER2( const char* uplo, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* x, const integer_t* incx,
- const dcomplex_t* y, const integer_t* incy, dcomplex_t* a,
- const integer_t* lda );
+void BLAS_CHER2( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* x, const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy, void* a, const std::ptrdiff_t* lda );
+void BLAS_ZHER2( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* x, const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy, void* a, const std::ptrdiff_t* lda );
 
 // Value-type variants of hpmv
-void BLAS_CHPMV( const char* uplo, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* ap, const fcomplex_t* x,
- const integer_t* incx, const fcomplex_t* beta, fcomplex_t* y,
- const integer_t* incy );
-void BLAS_ZHPMV( const char* uplo, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* ap, const dcomplex_t* x,
- const integer_t* incx, const dcomplex_t* beta, dcomplex_t* y,
- const integer_t* incy );
+void BLAS_CHPMV( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* ap, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
+void BLAS_ZHPMV( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* ap, const void* x, const std::ptrdiff_t* incx,
+ const void* beta, void* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of hpr
-void BLAS_CHPR( const char* uplo, const integer_t* n, const float* alpha,
- const fcomplex_t* x, const integer_t* incx, fcomplex_t* ap );
-void BLAS_ZHPR( const char* uplo, const integer_t* n, const double* alpha,
- const dcomplex_t* x, const integer_t* incx, dcomplex_t* ap );
+void BLAS_CHPR( const char* uplo, const std::ptrdiff_t* n, const float* alpha,
+ const void* x, const std::ptrdiff_t* incx, void* ap );
+void BLAS_ZHPR( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const void* x, const std::ptrdiff_t* incx,
+ void* ap );
 
 // Value-type variants of hpr2
-void BLAS_CHPR2( const char* uplo, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* x, const integer_t* incx,
- const fcomplex_t* y, const integer_t* incy, fcomplex_t* ap );
-void BLAS_ZHPR2( const char* uplo, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* x, const integer_t* incx,
- const dcomplex_t* y, const integer_t* incy, dcomplex_t* ap );
+void BLAS_CHPR2( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* x, const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy, void* ap );
+void BLAS_ZHPR2( const char* uplo, const std::ptrdiff_t* n, const void* alpha,
+ const void* x, const std::ptrdiff_t* incx, const void* y,
+ const std::ptrdiff_t* incy, void* ap );
 
 // Value-type variants of sbmv
-void BLAS_SSBMV( const char* uplo, const integer_t* n, const integer_t* k,
- const float* alpha, const float* a, const integer_t* lda,
- const float* x, const integer_t* incx, const float* beta, float* y,
- const integer_t* incy );
-void BLAS_DSBMV( const char* uplo, const integer_t* n, const integer_t* k,
- const double* alpha, const double* a, const integer_t* lda,
- const double* x, const integer_t* incx, const double* beta, double* y,
- const integer_t* incy );
+void BLAS_SSBMV( const char* uplo, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* x, const std::ptrdiff_t* incx,
+ const float* beta, float* y, const std::ptrdiff_t* incy );
+void BLAS_DSBMV( const char* uplo, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* x,
+ const std::ptrdiff_t* incx, const double* beta, double* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of spmv
-void BLAS_SSPMV( const char* uplo, const integer_t* n, const float* alpha,
- const float* ap, const float* x, const integer_t* incx,
- const float* beta, float* y, const integer_t* incy );
-void BLAS_DSPMV( const char* uplo, const integer_t* n, const double* alpha,
- const double* ap, const double* x, const integer_t* incx,
- const double* beta, double* y, const integer_t* incy );
+void BLAS_SSPMV( const char* uplo, const std::ptrdiff_t* n,
+ const float* alpha, const float* ap, const float* x,
+ const std::ptrdiff_t* incx, const float* beta, float* y,
+ const std::ptrdiff_t* incy );
+void BLAS_DSPMV( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* ap, const double* x,
+ const std::ptrdiff_t* incx, const double* beta, double* y,
+ const std::ptrdiff_t* incy );
 
 // Value-type variants of spr
-void BLAS_SSPR( const char* uplo, const integer_t* n, const float* alpha,
- const float* x, const integer_t* incx, float* ap );
-void BLAS_DSPR( const char* uplo, const integer_t* n, const double* alpha,
- const double* x, const integer_t* incx, double* ap );
+void BLAS_SSPR( const char* uplo, const std::ptrdiff_t* n, const float* alpha,
+ const float* x, const std::ptrdiff_t* incx, float* ap );
+void BLAS_DSPR( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* x, const std::ptrdiff_t* incx,
+ double* ap );
 
 // Value-type variants of spr2
-void BLAS_SSPR2( const char* uplo, const integer_t* n, const float* alpha,
- const float* x, const integer_t* incx, const float* y,
- const integer_t* incy, float* ap );
-void BLAS_DSPR2( const char* uplo, const integer_t* n, const double* alpha,
- const double* x, const integer_t* incx, const double* y,
- const integer_t* incy, double* ap );
+void BLAS_SSPR2( const char* uplo, const std::ptrdiff_t* n,
+ const float* alpha, const float* x, const std::ptrdiff_t* incx,
+ const float* y, const std::ptrdiff_t* incy, float* ap );
+void BLAS_DSPR2( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* x, const std::ptrdiff_t* incx,
+ const double* y, const std::ptrdiff_t* incy, double* ap );
 
 // Value-type variants of symv
-void BLAS_SSYMV( const char* uplo, const integer_t* n, const float* alpha,
- const float* a, const integer_t* lda, const float* x,
- const integer_t* incx, const float* beta, float* y,
- const integer_t* incy );
-void BLAS_DSYMV( const char* uplo, const integer_t* n, const double* alpha,
- const double* a, const integer_t* lda, const double* x,
- const integer_t* incx, const double* beta, double* y,
- const integer_t* incy );
+void BLAS_SSYMV( const char* uplo, const std::ptrdiff_t* n,
+ const float* alpha, const float* a, const std::ptrdiff_t* lda,
+ const float* x, const std::ptrdiff_t* incx, const float* beta,
+ float* y, const std::ptrdiff_t* incy );
+void BLAS_DSYMV( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* a, const std::ptrdiff_t* lda,
+ const double* x, const std::ptrdiff_t* incx, const double* beta,
+ double* y, const std::ptrdiff_t* incy );
 
 // Value-type variants of syr
-void BLAS_SSYR( const char* uplo, const integer_t* n, const float* alpha,
- const float* x, const integer_t* incx, float* a,
- const integer_t* lda );
-void BLAS_DSYR( const char* uplo, const integer_t* n, const double* alpha,
- const double* x, const integer_t* incx, double* a,
- const integer_t* lda );
+void BLAS_SSYR( const char* uplo, const std::ptrdiff_t* n, const float* alpha,
+ const float* x, const std::ptrdiff_t* incx, float* a,
+ const std::ptrdiff_t* lda );
+void BLAS_DSYR( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* x, const std::ptrdiff_t* incx,
+ double* a, const std::ptrdiff_t* lda );
 
 // Value-type variants of syr2
-void BLAS_SSYR2( const char* uplo, const integer_t* n, const float* alpha,
- const float* x, const integer_t* incx, const float* y,
- const integer_t* incy, float* a, const integer_t* lda );
-void BLAS_DSYR2( const char* uplo, const integer_t* n, const double* alpha,
- const double* x, const integer_t* incx, const double* y,
- const integer_t* incy, double* a, const integer_t* lda );
+void BLAS_SSYR2( const char* uplo, const std::ptrdiff_t* n,
+ const float* alpha, const float* x, const std::ptrdiff_t* incx,
+ const float* y, const std::ptrdiff_t* incy, float* a,
+ const std::ptrdiff_t* lda );
+void BLAS_DSYR2( const char* uplo, const std::ptrdiff_t* n,
+ const double* alpha, const double* x, const std::ptrdiff_t* incx,
+ const double* y, const std::ptrdiff_t* incy, double* a,
+ const std::ptrdiff_t* lda );
 
 // Value-type variants of tbmv
 void BLAS_STBMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const float* a,
- const integer_t* lda, float* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const float* a,
+ const std::ptrdiff_t* lda, float* x, const std::ptrdiff_t* incx );
 void BLAS_DTBMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const double* a,
- const integer_t* lda, double* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const double* a,
+ const std::ptrdiff_t* lda, double* x, const std::ptrdiff_t* incx );
 void BLAS_CTBMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const fcomplex_t* a,
- const integer_t* lda, fcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* a,
+ const std::ptrdiff_t* lda, void* x, const std::ptrdiff_t* incx );
 void BLAS_ZTBMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const dcomplex_t* a,
- const integer_t* lda, dcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* a,
+ const std::ptrdiff_t* lda, void* x, const std::ptrdiff_t* incx );
 
 // Value-type variants of tbsv
 void BLAS_STBSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const float* a,
- const integer_t* lda, float* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const float* a,
+ const std::ptrdiff_t* lda, float* x, const std::ptrdiff_t* incx );
 void BLAS_DTBSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const double* a,
- const integer_t* lda, double* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const double* a,
+ const std::ptrdiff_t* lda, double* x, const std::ptrdiff_t* incx );
 void BLAS_CTBSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const fcomplex_t* a,
- const integer_t* lda, fcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* a,
+ const std::ptrdiff_t* lda, void* x, const std::ptrdiff_t* incx );
 void BLAS_ZTBSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const integer_t* k, const dcomplex_t* a,
- const integer_t* lda, dcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* a,
+ const std::ptrdiff_t* lda, void* x, const std::ptrdiff_t* incx );
 
 // Value-type variants of tpmv
 void BLAS_STPMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const float* ap, float* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const float* ap, float* x,
+ const std::ptrdiff_t* incx );
 void BLAS_DTPMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const double* ap, double* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const double* ap, double* x,
+ const std::ptrdiff_t* incx );
 void BLAS_CTPMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const fcomplex_t* ap, fcomplex_t* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const void* ap, void* x,
+ const std::ptrdiff_t* incx );
 void BLAS_ZTPMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const dcomplex_t* ap, dcomplex_t* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const void* ap, void* x,
+ const std::ptrdiff_t* incx );
 
 // Value-type variants of tpsv
 void BLAS_STPSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const float* ap, float* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const float* ap, float* x,
+ const std::ptrdiff_t* incx );
 void BLAS_DTPSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const double* ap, double* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const double* ap, double* x,
+ const std::ptrdiff_t* incx );
 void BLAS_CTPSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const fcomplex_t* ap, fcomplex_t* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const void* ap, void* x,
+ const std::ptrdiff_t* incx );
 void BLAS_ZTPSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const dcomplex_t* ap, dcomplex_t* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const void* ap, void* x,
+ const std::ptrdiff_t* incx );
 
 // Value-type variants of trmv
 void BLAS_STRMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const float* a, const integer_t* lda, float* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const float* a, const std::ptrdiff_t* lda,
+ float* x, const std::ptrdiff_t* incx );
 void BLAS_DTRMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const double* a, const integer_t* lda, double* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const double* a, const std::ptrdiff_t* lda,
+ double* x, const std::ptrdiff_t* incx );
 void BLAS_CTRMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const fcomplex_t* a, const integer_t* lda,
- fcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const void* a, const std::ptrdiff_t* lda,
+ void* x, const std::ptrdiff_t* incx );
 void BLAS_ZTRMV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const dcomplex_t* a, const integer_t* lda,
- dcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const void* a, const std::ptrdiff_t* lda,
+ void* x, const std::ptrdiff_t* incx );
 
 // Value-type variants of trsv
 void BLAS_STRSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const float* a, const integer_t* lda, float* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const float* a, const std::ptrdiff_t* lda,
+ float* x, const std::ptrdiff_t* incx );
 void BLAS_DTRSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const double* a, const integer_t* lda, double* x,
- const integer_t* incx );
+ const std::ptrdiff_t* n, const double* a, const std::ptrdiff_t* lda,
+ double* x, const std::ptrdiff_t* incx );
 void BLAS_CTRSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const fcomplex_t* a, const integer_t* lda,
- fcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const void* a, const std::ptrdiff_t* lda,
+ void* x, const std::ptrdiff_t* incx );
 void BLAS_ZTRSV( const char* uplo, const char* trans, const char* diag,
- const integer_t* n, const dcomplex_t* a, const integer_t* lda,
- dcomplex_t* x, const integer_t* incx );
+ const std::ptrdiff_t* n, const void* a, const std::ptrdiff_t* lda,
+ void* x, const std::ptrdiff_t* incx );
 
 //
 // BLAS level3 routines
 //
 
 // Value-type variants of gemm
-void BLAS_SGEMM( const char* transa, const char* transb, const integer_t* m,
- const integer_t* n, const integer_t* k, const float* alpha,
- const float* a, const integer_t* lda, const float* b,
- const integer_t* ldb, const float* beta, float* c,
- const integer_t* ldc );
-void BLAS_DGEMM( const char* transa, const char* transb, const integer_t* m,
- const integer_t* n, const integer_t* k, const double* alpha,
- const double* a, const integer_t* lda, const double* b,
- const integer_t* ldb, const double* beta, double* c,
- const integer_t* ldc );
-void BLAS_CGEMM( const char* transa, const char* transb, const integer_t* m,
- const integer_t* n, const integer_t* k, const fcomplex_t* alpha,
- const fcomplex_t* a, const integer_t* lda, const fcomplex_t* b,
- const integer_t* ldb, const fcomplex_t* beta, fcomplex_t* c,
- const integer_t* ldc );
-void BLAS_ZGEMM( const char* transa, const char* transb, const integer_t* m,
- const integer_t* n, const integer_t* k, const dcomplex_t* alpha,
- const dcomplex_t* a, const integer_t* lda, const dcomplex_t* b,
- const integer_t* ldb, const dcomplex_t* beta, dcomplex_t* c,
- const integer_t* ldc );
+void BLAS_SGEMM( const char* transa, const char* transb,
+ const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* b, const std::ptrdiff_t* ldb,
+ const float* beta, float* c, const std::ptrdiff_t* ldc );
+void BLAS_DGEMM( const char* transa, const char* transb,
+ const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* b, const std::ptrdiff_t* ldb,
+ const double* beta, double* c, const std::ptrdiff_t* ldc );
+void BLAS_CGEMM( const char* transa, const char* transb,
+ const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
+void BLAS_ZGEMM( const char* transa, const char* transb,
+ const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
 
 // Value-type variants of hemm
-void BLAS_CHEMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const fcomplex_t* alpha, const fcomplex_t* a,
- const integer_t* lda, const fcomplex_t* b, const integer_t* ldb,
- const fcomplex_t* beta, fcomplex_t* c, const integer_t* ldc );
-void BLAS_ZHEMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const dcomplex_t* alpha, const dcomplex_t* a,
- const integer_t* lda, const dcomplex_t* b, const integer_t* ldb,
- const dcomplex_t* beta, dcomplex_t* c, const integer_t* ldc );
+void BLAS_CHEMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
+void BLAS_ZHEMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
 
 // Value-type variants of her2k
-void BLAS_CHER2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const fcomplex_t* alpha, const fcomplex_t* a,
- const integer_t* lda, const fcomplex_t* b, const integer_t* ldb,
- const float* beta, fcomplex_t* c, const integer_t* ldc );
-void BLAS_ZHER2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const dcomplex_t* alpha, const dcomplex_t* a,
- const integer_t* lda, const dcomplex_t* b, const integer_t* ldb,
- const double* beta, dcomplex_t* c, const integer_t* ldc );
+void BLAS_CHER2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* b,
+ const std::ptrdiff_t* ldb, const float* beta, void* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_ZHER2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* b,
+ const std::ptrdiff_t* ldb, const double* beta, void* c,
+ const std::ptrdiff_t* ldc );
 
 // Value-type variants of herk
-void BLAS_CHERK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const float* alpha, const fcomplex_t* a,
- const integer_t* lda, const float* beta, fcomplex_t* c,
- const integer_t* ldc );
-void BLAS_ZHERK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const double* alpha, const dcomplex_t* a,
- const integer_t* lda, const double* beta, dcomplex_t* c,
- const integer_t* ldc );
+void BLAS_CHERK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const float* alpha, const void* a,
+ const std::ptrdiff_t* lda, const float* beta, void* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_ZHERK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const double* alpha, const void* a,
+ const std::ptrdiff_t* lda, const double* beta, void* c,
+ const std::ptrdiff_t* ldc );
 
 // Value-type variants of symm
-void BLAS_SSYMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const float* alpha, const float* a,
- const integer_t* lda, const float* b, const integer_t* ldb,
- const float* beta, float* c, const integer_t* ldc );
-void BLAS_DSYMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const double* alpha, const double* a,
- const integer_t* lda, const double* b, const integer_t* ldb,
- const double* beta, double* c, const integer_t* ldc );
-void BLAS_CSYMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const fcomplex_t* alpha, const fcomplex_t* a,
- const integer_t* lda, const fcomplex_t* b, const integer_t* ldb,
- const fcomplex_t* beta, fcomplex_t* c, const integer_t* ldc );
-void BLAS_ZSYMM( const char* side, const char* uplo, const integer_t* m,
- const integer_t* n, const dcomplex_t* alpha, const dcomplex_t* a,
- const integer_t* lda, const dcomplex_t* b, const integer_t* ldb,
- const dcomplex_t* beta, dcomplex_t* c, const integer_t* ldc );
+void BLAS_SSYMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* b, const std::ptrdiff_t* ldb,
+ const float* beta, float* c, const std::ptrdiff_t* ldc );
+void BLAS_DSYMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* b, const std::ptrdiff_t* ldb,
+ const double* beta, double* c, const std::ptrdiff_t* ldc );
+void BLAS_CSYMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
+void BLAS_ZSYMM( const char* side, const char* uplo, const std::ptrdiff_t* m,
+ const std::ptrdiff_t* n, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* b, const std::ptrdiff_t* ldb,
+ const void* beta, void* c, const std::ptrdiff_t* ldc );
 
 // Value-type variants of syr2k
-void BLAS_SSYR2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const float* alpha, const float* a,
- const integer_t* lda, const float* b, const integer_t* ldb,
- const float* beta, float* c, const integer_t* ldc );
-void BLAS_DSYR2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const double* alpha, const double* a,
- const integer_t* lda, const double* b, const integer_t* ldb,
- const double* beta, double* c, const integer_t* ldc );
-void BLAS_CSYR2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const fcomplex_t* alpha, const fcomplex_t* a,
- const integer_t* lda, const fcomplex_t* b, const integer_t* ldb,
- const fcomplex_t* beta, fcomplex_t* c, const integer_t* ldc );
-void BLAS_ZSYR2K( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const dcomplex_t* alpha, const dcomplex_t* a,
- const integer_t* lda, const dcomplex_t* b, const integer_t* ldb,
- const dcomplex_t* beta, dcomplex_t* c, const integer_t* ldc );
+void BLAS_SSYR2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const float* alpha,
+ const float* a, const std::ptrdiff_t* lda, const float* b,
+ const std::ptrdiff_t* ldb, const float* beta, float* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_DSYR2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const double* alpha,
+ const double* a, const std::ptrdiff_t* lda, const double* b,
+ const std::ptrdiff_t* ldb, const double* beta, double* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_CSYR2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* b,
+ const std::ptrdiff_t* ldb, const void* beta, void* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_ZSYR2K( const char* uplo, const char* trans,
+ const std::ptrdiff_t* n, const std::ptrdiff_t* k, const void* alpha,
+ const void* a, const std::ptrdiff_t* lda, const void* b,
+ const std::ptrdiff_t* ldb, const void* beta, void* c,
+ const std::ptrdiff_t* ldc );
 
 // Value-type variants of syrk
-void BLAS_SSYRK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const float* alpha, const float* a,
- const integer_t* lda, const float* beta, float* c,
- const integer_t* ldc );
-void BLAS_DSYRK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const double* alpha, const double* a,
- const integer_t* lda, const double* beta, double* c,
- const integer_t* ldc );
-void BLAS_CSYRK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const fcomplex_t* alpha, const fcomplex_t* a,
- const integer_t* lda, const fcomplex_t* beta, fcomplex_t* c,
- const integer_t* ldc );
-void BLAS_ZSYRK( const char* uplo, const char* trans, const integer_t* n,
- const integer_t* k, const dcomplex_t* alpha, const dcomplex_t* a,
- const integer_t* lda, const dcomplex_t* beta, dcomplex_t* c,
- const integer_t* ldc );
+void BLAS_SSYRK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const float* alpha, const float* a,
+ const std::ptrdiff_t* lda, const float* beta, float* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_DSYRK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const double* alpha, const double* a,
+ const std::ptrdiff_t* lda, const double* beta, double* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_CSYRK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* beta, void* c,
+ const std::ptrdiff_t* ldc );
+void BLAS_ZSYRK( const char* uplo, const char* trans, const std::ptrdiff_t* n,
+ const std::ptrdiff_t* k, const void* alpha, const void* a,
+ const std::ptrdiff_t* lda, const void* beta, void* c,
+ const std::ptrdiff_t* ldc );
 
 // Value-type variants of trmm
 void BLAS_STRMM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const float* alpha, const float* a, const integer_t* lda, float* b,
- const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const float* alpha, const float* a, const std::ptrdiff_t* lda,
+ float* b, const std::ptrdiff_t* ldb );
 void BLAS_DTRMM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const double* alpha, const double* a, const integer_t* lda, double* b,
- const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const double* alpha, const double* a, const std::ptrdiff_t* lda,
+ double* b, const std::ptrdiff_t* ldb );
 void BLAS_CTRMM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* a, const integer_t* lda,
- fcomplex_t* b, const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* a, const std::ptrdiff_t* lda, void* b,
+ const std::ptrdiff_t* ldb );
 void BLAS_ZTRMM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* a, const integer_t* lda,
- dcomplex_t* b, const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* a, const std::ptrdiff_t* lda, void* b,
+ const std::ptrdiff_t* ldb );
 
 // Value-type variants of trsm
 void BLAS_STRSM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const float* alpha, const float* a, const integer_t* lda, float* b,
- const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const float* alpha, const float* a, const std::ptrdiff_t* lda,
+ float* b, const std::ptrdiff_t* ldb );
 void BLAS_DTRSM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const double* alpha, const double* a, const integer_t* lda, double* b,
- const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const double* alpha, const double* a, const std::ptrdiff_t* lda,
+ double* b, const std::ptrdiff_t* ldb );
 void BLAS_CTRSM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const fcomplex_t* alpha, const fcomplex_t* a, const integer_t* lda,
- fcomplex_t* b, const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* a, const std::ptrdiff_t* lda, void* b,
+ const std::ptrdiff_t* ldb );
 void BLAS_ZTRSM( const char* side, const char* uplo, const char* transa,
- const char* diag, const integer_t* m, const integer_t* n,
- const dcomplex_t* alpha, const dcomplex_t* a, const integer_t* lda,
- dcomplex_t* b, const integer_t* ldb );
+ const char* diag, const std::ptrdiff_t* m, const std::ptrdiff_t* n,
+ const void* alpha, const void* a, const std::ptrdiff_t* lda, void* b,
+ const std::ptrdiff_t* ldb );
 
 }
 

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas_names.h
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas_names.h (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/blas_names.h 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,7 +14,7 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_DETAIL_BLAS_NAMES_H
 #define BOOST_NUMERIC_BINDINGS_BLAS_DETAIL_BLAS_NAMES_H
 
-#include <boost/numeric/bindings/traits/fortran.h>
+#include <boost/numeric/bindings/detail/fortran.h>
 
 //
 // BLAS level1 routines

Added: sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/default_order.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/detail/default_order.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -0,0 +1,38 @@
+//
+// 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_BLAS_DETAIL_DEFAULT_ORDER_HPP
+#define BOOST_NUMERIC_BINDINGS_BLAS_DETAIL_DEFAULT_ORDER_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/bindings/is_row_major.hpp>
+#include <boost/numeric/bindings/tag.hpp>
+#include <boost/numeric/bindings/detail/property_map.hpp>
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace blas {
+namespace detail {
+
+template< typename T >
+struct default_order {
+ typedef typename mpl::if_<
+ bindings::detail::is_same_at< T, tag::value_transform, tag::conjugate >,
+ typename mpl::if_< is_row_major< T >, tag::column_major, tag::row_major >::type,
+ tag::column_major
+ >::type type;
+};
+
+} // namespace detail
+} // namespace blas
+} // namespace bindings
+} // namespace numeric
+} // namespace boost
+
+#endif

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/asum.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/asum.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/asum.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,78 +14,161 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ASUM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ASUM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline float asum( const integer_t n, const float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_sasum( n, x, incx );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float asum( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ return cblas_sasum( cblas_option< Order >::value, n, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double asum( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ return cblas_dasum( cblas_option< Order >::value, n, x, incx );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float asum( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasSasum( n, x, incx );
-#else
- return BLAS_SASUM( &n, x, &incx );
-#endif
 }
 
-inline double asum( const integer_t n, const double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_dasum( n, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double asum( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasDasum( n, x, incx );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline float asum( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_SASUM( &n, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline double asum( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return BLAS_DASUM( &n, x, &incx );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to asum.
+//
+template< typename Value >
 struct asum_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX >
     static return_type invoke( const VectorX& x ) {
- return detail::asum( traits::vector_size(x),
- traits::vector_storage(x), traits::vector_stride(x) );
+
+ return detail::asum( size(x), begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call asum
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the asum_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for asum. Its overload differs for
+//
 template< typename VectorX >
-inline typename asum_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename asum_impl< typename value< VectorX >::type >::return_type
 asum( const VectorX& x ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- return asum_impl< value_type >::invoke( x );
+ return asum_impl< typename value< VectorX >::type >::invoke( x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/axpy.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/axpy.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/axpy.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,114 +14,262 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_AXPY_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_AXPY_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void axpy( const integer_t n, const float a, const float* x,
- const integer_t incx, float* y, const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_saxpy( n, a, x, incx, y, incy );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const float a,
+ const float* x, const std::ptrdiff_t incx, float* y,
+ const std::ptrdiff_t incy ) {
+ cblas_saxpy( cblas_option< Order >::value, n, a, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const double a,
+ const double* x, const std::ptrdiff_t incx, double* y,
+ const std::ptrdiff_t incy ) {
+ cblas_daxpy( cblas_option< Order >::value, n, a, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ cblas_caxpy( cblas_option< Order >::value, n, &a, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ cblas_zaxpy( cblas_option< Order >::value, n, &a, x, incx, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const float a,
+ const float* x, const std::ptrdiff_t incx, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSaxpy( n, a, x, incx, y, incy );
-#else
- BLAS_SAXPY( &n, &a, x, &incx, y, &incy );
-#endif
 }
 
-inline void axpy( const integer_t n, const double a, const double* x,
- const integer_t incx, double* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_daxpy( n, a, x, incx, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const double a,
+ const double* x, const std::ptrdiff_t incx, double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDaxpy( n, a, x, incx, y, incy );
-#else
- BLAS_DAXPY( &n, &a, x, &incx, y, &incy );
-#endif
 }
 
-inline void axpy( const integer_t n, const traits::complex_f a,
- const traits::complex_f* x, const integer_t incx,
- traits::complex_f* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_caxpy( n, traits::void_ptr(&a), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCaxpy( n, traits::void_ptr(a), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy );
-#else
- BLAS_CAXPY( &n, traits::complex_ptr(&a), traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCaxpy( n, a, x, incx, y, incy );
 }
 
-inline void axpy( const integer_t n, const traits::complex_d a,
- const traits::complex_d* x, const integer_t incx,
- traits::complex_d* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zaxpy( n, traits::void_ptr(&a), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZAXPY( &n, traits::complex_ptr(&a), traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const float a,
+ const float* x, const std::ptrdiff_t incx, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SAXPY( &n, &a, x, &incx, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const double a,
+ const double* x, const std::ptrdiff_t incx, double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DAXPY( &n, &a, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CAXPY( &n, &a, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void axpy( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZAXPY( &n, &a, x, &incx, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to axpy.
+//
+template< typename Value >
 struct axpy_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( const value_type a, const VectorX& x,
             VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::axpy( traits::vector_size(x), a,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+
+ detail::axpy( size(x), a, begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call axpy
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the axpy_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for axpy. Its overload differs for
+// * VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename axpy_impl< typename value< VectorX >::type >::return_type
+axpy( const typename value< VectorX >::type a, const VectorX& x,
+ VectorY& y ) {
+ axpy_impl< typename value< VectorX >::type >::invoke( a, x, y );
+}
+
+//
+// Overloaded function for axpy. Its overload differs for
+// * const VectorY&
+//
 template< typename VectorX, typename VectorY >
-inline typename axpy_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-axpy( const typename traits::vector_traits< VectorX >::value_type a,
- const VectorX& x, VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- axpy_impl< value_type >::invoke( a, x, y );
+inline typename axpy_impl< typename value< VectorX >::type >::return_type
+axpy( const typename value< VectorX >::type a, const VectorX& x,
+ const VectorY& y ) {
+ axpy_impl< typename value< VectorX >::type >::invoke( a, x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/copy.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/copy.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/copy.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,109 +14,253 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_COPY_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_COPY_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void copy( const integer_t n, const float* x, const integer_t incx,
- const float* y, const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_scopy( n, x, incx, y, incy );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ cblas_scopy( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ cblas_dcopy( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_ccopy( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ cblas_zcopy( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasScopy( n, x, incx, y, incy );
-#else
- BLAS_SCOPY( &n, x, &incx, y, &incy );
-#endif
 }
 
-inline void copy( const integer_t n, const double* x, const integer_t incx,
- const double* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dcopy( n, x, incx, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDcopy( n, x, incx, y, incy );
-#else
- BLAS_DCOPY( &n, x, &incx, y, &incy );
-#endif
 }
 
-inline void copy( const integer_t n, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ccopy( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCcopy( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#else
- BLAS_CCOPY( &n, traits::complex_ptr(x), &incx, traits::complex_ptr(y),
- &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCcopy( n, x, incx, y, incy );
 }
 
-inline void copy( const integer_t n, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zcopy( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZCOPY( &n, traits::complex_ptr(x), &incx, traits::complex_ptr(y),
- &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SCOPY( &n, x, &incx, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DCOPY( &n, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CCOPY( &n, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void copy( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZCOPY( &n, x, &incx, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to copy.
+//
+template< typename Value >
 struct copy_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
- static return_type invoke( const VectorX& x, const VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::copy( traits::vector_size(x), traits::vector_storage(x),
- traits::vector_stride(x), traits::vector_storage(y),
- traits::vector_stride(y) );
+ static return_type invoke( const VectorX& x, VectorY& y ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+
+ detail::copy( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call copy
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the copy_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for copy. Its overload differs for
+// * VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename copy_impl< typename value< VectorX >::type >::return_type
+copy( const VectorX& x, VectorY& y ) {
+ copy_impl< typename value< VectorX >::type >::invoke( x, y );
+}
+
+//
+// Overloaded function for copy. Its overload differs for
+// * const VectorY&
+//
 template< typename VectorX, typename VectorY >
-inline typename copy_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename copy_impl< typename value< VectorX >::type >::return_type
 copy( const VectorX& x, const VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- copy_impl< value_type >::invoke( x, y );
+ copy_impl< typename value< VectorX >::type >::invoke( x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dot.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dot.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dot.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,83 +14,171 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOT_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOT_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline float dot( const integer_t n, const float* x, const integer_t incx,
- const float* y, const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_sdot( n, x, incx, y, incy );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float dot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy ) {
+ return cblas_sdot( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double dot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy ) {
+ return cblas_ddot( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float dot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasSdot( n, x, incx, y, incy );
-#else
- return BLAS_SDOT( &n, x, &incx, y, &incy );
-#endif
 }
 
-inline double dot( const integer_t n, const double* x, const integer_t incx,
- const double* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_ddot( n, x, incx, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double dot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasDdot( n, x, incx, y, incy );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline float dot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_SDOT( &n, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline double dot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return BLAS_DDOT( &n, x, &incx, y, &incy );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to dot.
+//
+template< typename Value >
 struct dot_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( const VectorX& x, const VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- return detail::dot( traits::vector_size(x),
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+
+ return detail::dot( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call dot
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the dot_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for dot. Its overload differs for
+//
 template< typename VectorX, typename VectorY >
-inline typename dot_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename dot_impl< typename value< VectorX >::type >::return_type
 dot( const VectorX& x, const VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- return dot_impl< value_type >::invoke( x, y );
+ return dot_impl< typename value< VectorX >::type >::invoke( x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotc.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotc.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotc.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,90 +14,173 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOTC_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOTC_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline fcomplex_t dotc( const integer_t n, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_cdotc_sub( n, traits::void_ptr(x), incx, traits::void_ptr(y),
- incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- return cublasCdotc( n, traits::void_ptr(x), incx, traits::void_ptr(y),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ return cblas_cdotc_sub( cblas_option< Order >::value, n, x, incx, y,
             incy );
-#else
- return BLAS_CDOTC( &n, traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
 }
 
-inline dcomplex_t dotc( const integer_t n, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_zdotc_sub( n, traits::void_ptr(x), incx, traits::void_ptr(y),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ return cblas_zdotc_sub( cblas_option< Order >::value, n, x, incx, y,
             incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return cublasCdotc( n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return // NOT FOUND();
+}
+
 #else
- return BLAS_ZDOTC( &n, traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_CDOTC( &n, x, &incx, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotc( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_ZDOTC( &n, x, &incx, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to dotc.
+//
+template< typename Value >
 struct dotc_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( const VectorX& x, const VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- return detail::dotc( traits::vector_size(x),
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+
+ return detail::dotc( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call dotc
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the dotc_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for dotc. Its overload differs for
+//
 template< typename VectorX, typename VectorY >
-inline typename dotc_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename dotc_impl< typename value< VectorX >::type >::return_type
 dotc( const VectorX& x, const VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- return dotc_impl< value_type >::invoke( x, y );
+ return dotc_impl< typename value< VectorX >::type >::invoke( x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotu.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotu.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/dotu.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,91 +14,173 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOTU_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DOTU_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline fcomplex_t dotu( const integer_t n, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_cdotu_sub( n, traits::void_ptr(x), incx, traits::void_ptr(y),
- incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- return cublasCdotu( n, traits::void_ptr(x), incx, traits::void_ptr(y),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ return cblas_cdotu_sub( cblas_option< Order >::value, n, x, incx, y,
             incy );
-#else
- return BLAS_CDOTU( &n, traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
 }
 
-inline dcomplex_t dotu( const integer_t n, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_zdotu_sub( n, traits::void_ptr(x), incx, traits::void_ptr(y),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ return cblas_zdotu_sub( cblas_option< Order >::value, n, x, incx, y,
             incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- return cublasZdotu( n, traits::void_ptr(x), incx, traits::void_ptr(y),
- incy );
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return cublasCdotu( n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return cublasZdotu( n, x, incx, y, incy );
+}
+
 #else
- return BLAS_ZDOTU( &n, traits::complex_ptr(x), &incx,
- traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_CDOTU( &n, x, &incx, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void dotu( Order, const std::ptrdiff_t n,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_ZDOTU( &n, x, &incx, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to dotu.
+//
+template< typename Value >
 struct dotu_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( const VectorX& x, const VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- return detail::dotu( traits::vector_size(x),
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+
+ return detail::dotu( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call dotu
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the dotu_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for dotu. Its overload differs for
+//
 template< typename VectorX, typename VectorY >
-inline typename dotu_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename dotu_impl< typename value< VectorX >::type >::return_type
 dotu( const VectorX& x, const VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- return dotu_impl< value_type >::invoke( x, y );
+ return dotu_impl< typename value< VectorX >::type >::invoke( x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/drot.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/drot.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/drot.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -15,9 +15,9 @@
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_DROT_HPP
 
 // Include header of configured BLAS interface
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+#if defined BOOST_NUMERIC_BINDINGS_BLAS_HAVE_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+#elif defined BOOST_NUMERIC_BINDINGS_BLAS_HAVE_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
@@ -53,10 +53,25 @@
 }
 
 
+struct blas_backend {
+
+ static void drot( ... ) {
+ }
+
+};
+
+
+
+
+
+
+
+
+
 } // namespace detail
 
 // value-type based template
-template< typename ValueType >
+template< typename ValueType, typename Backend = use_default >
 struct drot_impl {
 
     typedef ValueType value_type;

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/nrm2.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/nrm2.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/nrm2.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,78 +14,161 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_NRM2_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_NRM2_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline float nrm2( const integer_t n, const float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_snrm2( n, x, incx );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float nrm2( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ return cblas_snrm2( cblas_option< Order >::value, n, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double nrm2( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ return cblas_dnrm2( cblas_option< Order >::value, n, x, incx );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline float nrm2( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasSnrm2( n, x, incx );
-#else
- return BLAS_SNRM2( &n, x, &incx );
-#endif
 }
 
-inline double nrm2( const integer_t n, const double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_dnrm2( n, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double nrm2( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return cublasDnrm2( n, x, incx );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline float nrm2( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ return BLAS_SNRM2( &n, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline double nrm2( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return BLAS_DNRM2( &n, x, &incx );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to nrm2.
+//
+template< typename Value >
 struct nrm2_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX >
     static return_type invoke( const VectorX& x ) {
- return detail::nrm2( traits::vector_size(x),
- traits::vector_storage(x), traits::vector_stride(x) );
+
+ return detail::nrm2( size(x), begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call nrm2
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the nrm2_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for nrm2. Its overload differs for
+//
 template< typename VectorX >
-inline typename nrm2_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename nrm2_impl< typename value< VectorX >::type >::return_type
 nrm2( const VectorX& x ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- return nrm2_impl< value_type >::invoke( x );
+ return nrm2_impl< typename value< VectorX >::type >::invoke( x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rot.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rot.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rot.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,87 +14,190 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROT_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROT_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void rot( const integer_t n, const float* x, const integer_t incx,
- float* y, const integer_t incy, const float c, const float s ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_srot( n, x, incx, y, incy, c, s );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ const float c, const float s ) {
+ cblas_srot( cblas_option< Order >::value, n, x, incx, y, incy, c, s );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ const double c, const double s ) {
+ cblas_drot( cblas_option< Order >::value, n, x, incx, y, incy, c, s );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ const float c, const float s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSrot( n, x, incx, y, incy, c, s );
-#else
- BLAS_SROT( &n, x, &incx, y, &incy, &c, &s );
-#endif
 }
 
-inline void rot( const integer_t n, const double* x, const integer_t incx,
- double* y, const integer_t incy, const double c, const double s ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_drot( n, x, incx, y, incy, c, s );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ const double c, const double s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDrot( n, x, incx, y, incy, c, s );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ const float c, const float s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SROT( &n, x, &incx, y, &incy, &c, &s );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void rot( Order, const std::ptrdiff_t n, const double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ const double c, const double s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DROT( &n, x, &incx, y, &incy, &c, &s );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to rot.
+//
+template< typename Value >
 struct rot_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( const VectorX& x, VectorY& y,
             const real_type c, const real_type s ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::rot( traits::vector_size(x), traits::vector_storage(x),
- traits::vector_stride(x), traits::vector_storage(y),
- traits::vector_stride(y), c, s );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+
+ detail::rot( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y), c, s );
     }
 };
 
-// generic template function to call rot
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the rot_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for rot. Its overload differs for
+// * VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename rot_impl< typename value< VectorX >::type >::return_type
+rot( const VectorX& x, VectorY& y, const typename remove_imaginary<
+ typename value< VectorX >::type >::type c,
+ const typename remove_imaginary< typename value<
+ VectorX >::type >::type s ) {
+ rot_impl< typename value< VectorX >::type >::invoke( x, y, c, s );
+}
+
+//
+// Overloaded function for rot. Its overload differs for
+// * const VectorY&
+//
 template< typename VectorX, typename VectorY >
-inline typename rot_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-rot( const VectorX& x, VectorY& y, const typename traits::type_traits<
- typename traits::vector_traits< VectorX >::value_type >::real_type c,
- const typename traits::type_traits< typename traits::vector_traits<
- VectorX >::value_type >::real_type s ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- rot_impl< value_type >::invoke( x, y, c, s );
+inline typename rot_impl< typename value< VectorX >::type >::return_type
+rot( const VectorX& x, const VectorY& y,
+ const typename remove_imaginary< typename value<
+ VectorX >::type >::type c, const typename remove_imaginary<
+ typename value< VectorX >::type >::type s ) {
+ rot_impl< typename value< VectorX >::type >::invoke( x, y, c, s );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotg.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotg.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotg.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,82 +14,427 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTG_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTG_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void rotg( float& a, float& b, float& c, float& s ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_srotg( &a, &b, &c, &s );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotg( Order, float& a, float& b, float& c, float& s ) {
+ cblas_srotg( cblas_option< Order >::value, &a, &b, &c, &s );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotg( Order, double& a, double& b, double& c, double& s ) {
+ cblas_drotg( cblas_option< Order >::value, &a, &b, &c, &s );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotg( Order, float& a, float& b, float& c, float& s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSrotg( &a, &b, &c, &s );
-#else
- BLAS_SROTG( &a, &b, &c, &s );
-#endif
 }
 
-inline void rotg( double& a, double& b, double& c, double& s ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_drotg( &a, &b, &c, &s );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotg( Order, double& a, double& b, double& c, double& s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDrotg( &a, &b, &c, &s );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void rotg( Order, float& a, float& b, float& c, float& s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SROTG( &a, &b, &c, &s );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void rotg( Order, double& a, double& b, double& c, double& s ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DROTG( &a, &b, &c, &s );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to rotg.
+//
+template< typename Value >
 struct rotg_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< >
     static return_type invoke( real_type& a, real_type& b, real_type& c,
             real_type& s ) {
+
         detail::rotg( a, b, c, s );
     }
 };
 
-// generic template function to call rotg
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the rotg_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, typename remove_imaginary< typename value<
+ TODO >::type >::type& c, typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, typename remove_imaginary< typename value<
+ TODO >::type >::type& c, typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b, typename remove_imaginary<
+ typename value< TODO >::type >::type& c, typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b, typename remove_imaginary<
+ typename value< TODO >::type >::type& c, typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, const typename remove_imaginary<
+ typename value< TODO >::type >::type& c, typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, const typename remove_imaginary<
+ typename value< TODO >::type >::type& c, typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& c, typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& c, typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, typename remove_imaginary< typename value<
+ TODO >::type >::type& c, const typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, typename remove_imaginary< typename value<
+ TODO >::type >::type& c, const typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b, typename remove_imaginary<
+ typename value< TODO >::type >::type& c,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b, typename remove_imaginary<
+ typename value< TODO >::type >::type& c,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, const typename remove_imaginary<
+ typename value< TODO >::type >::type& c,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, typename remove_imaginary< typename value<
+ TODO >::type >::type& b, const typename remove_imaginary<
+ typename value< TODO >::type >::type& c,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
+template< >
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& c, const typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
+}
+
+//
+// Overloaded function for rotg. Its overload differs for
+// * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+ // * const typename remove_imaginary< typename value< TODO >::type >::type&
+//
 template< >
-inline typename rotg_impl< typename traits::TODO_traits<
- TODO >::value_type >::return_type
-rotg( typename traits::type_traits< typename traits::TODO_traits<
- TODO >::value_type >::real_type& a, typename traits::type_traits<
- typename traits::TODO_traits< TODO >::value_type >::real_type& b,
- typename traits::type_traits< typename traits::TODO_traits<
- TODO >::value_type >::real_type& c, typename traits::type_traits<
- typename traits::TODO_traits< TODO >::value_type >::real_type& s ) {
- typedef typename traits::TODO_traits< TODO >::value_type value_type;
- rotg_impl< value_type >::invoke( a, b, c, s );
+inline typename rotg_impl< typename value< TODO >::type >::return_type
+rotg( const typename remove_imaginary< typename value<
+ TODO >::type >::type& a, const typename remove_imaginary<
+ typename value< TODO >::type >::type& b,
+ const typename remove_imaginary< typename value<
+ TODO >::type >::type& c, const typename remove_imaginary<
+ typename value< TODO >::type >::type& s ) {
+ rotg_impl< typename value< TODO >::type >::invoke( a, b, c, s );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,89 +14,287 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void rotm( const integer_t n, float* x, const integer_t incx, float* y,
- const integer_t incy, float* param ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_srotm( n, x, incx, y, incy, param );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ float* param ) {
+ cblas_srotm( cblas_option< Order >::value, n, x, incx, y, incy, param );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ double* param ) {
+ cblas_drotm( cblas_option< Order >::value, n, x, incx, y, incy, param );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ float* param ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSrotm( n, x, incx, y, incy, param );
-#else
- BLAS_SROTM( &n, x, &incx, y, &incy, param );
-#endif
 }
 
-inline void rotm( const integer_t n, double* x, const integer_t incx,
- double* y, const integer_t incy, double* param ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_drotm( n, x, incx, y, incy, param );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ double* param ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDrotm( n, x, incx, y, incy, param );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy,
+ float* param ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SROTM( &n, x, &incx, y, &incy, param );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void rotm( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy,
+ double* param ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DROTM( &n, x, &incx, y, &incy, param );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to rotm.
+//
+template< typename Value >
 struct rotm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename VectorPARAM >
- static return_type invoke( const integer_t n, VectorX& x,
- const integer_t incx, VectorY& y, const integer_t incy,
+ static return_type invoke( const std::ptrdiff_t n, VectorX& x,
+ const std::ptrdiff_t incx, VectorY& y, const std::ptrdiff_t incy,
             VectorPARAM& param ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorPARAM >::value_type >::value) );
- detail::rotm( n, traits::vector_storage(x), incx,
- traits::vector_storage(y), incy,
- traits::vector_storage(param) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorPARAM >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorPARAM >::value ) );
+
+ detail::rotm( n, begin_value(x), incx, begin_value(y), incy,
+ begin_value(param) );
     }
 };
 
-// generic template function to call rotm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the rotm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * VectorX&
+ // * VectorY&
+ // * VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, VectorX& x, const std::ptrdiff_t incx,
+ VectorY& y, const std::ptrdiff_t incy, VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * const VectorX&
+ // * VectorY&
+ // * VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, const VectorX& x,
+ const std::ptrdiff_t incx, VectorY& y, const std::ptrdiff_t incy,
+ VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * VectorX&
+ // * const VectorY&
+ // * VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, VectorX& x, const std::ptrdiff_t incx,
+ const VectorY& y, const std::ptrdiff_t incy, VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * const VectorX&
+ // * const VectorY&
+ // * VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, const VectorX& x,
+ const std::ptrdiff_t incx, const VectorY& y,
+ const std::ptrdiff_t incy, VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * VectorX&
+ // * VectorY&
+ // * const VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, VectorX& x, const std::ptrdiff_t incx,
+ VectorY& y, const std::ptrdiff_t incy, const VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * const VectorX&
+ // * VectorY&
+ // * const VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, const VectorX& x,
+ const std::ptrdiff_t incx, VectorY& y, const std::ptrdiff_t incy,
+ const VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * VectorX&
+ // * const VectorY&
+ // * const VectorPARAM&
+//
+template< typename VectorX, typename VectorY, typename VectorPARAM >
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, VectorX& x, const std::ptrdiff_t incx,
+ const VectorY& y, const std::ptrdiff_t incy,
+ const VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
+}
+
+//
+// Overloaded function for rotm. Its overload differs for
+// * const VectorX&
+ // * const VectorY&
+ // * const VectorPARAM&
+//
 template< typename VectorX, typename VectorY, typename VectorPARAM >
-inline typename rotm_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-rotm( const integer_t n, VectorX& x, const integer_t incx, VectorY& y,
- const integer_t incy, VectorPARAM& param ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- rotm_impl< value_type >::invoke( n, x, incx, y, incy, param );
+inline typename rotm_impl< typename value< VectorX >::type >::return_type
+rotm( const std::ptrdiff_t n, const VectorX& x,
+ const std::ptrdiff_t incx, const VectorY& y,
+ const std::ptrdiff_t incy, const VectorPARAM& param ) {
+ rotm_impl< typename value< VectorX >::type >::invoke( n, x, incx, y,
+ incy, param );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotmg.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotmg.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/rotmg.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,87 +14,530 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTMG_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_ROTMG_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void rotmg( float& d1, float& d2, float& x1, const float y1,
- float* sparam ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_srotmg( &d1, &d2, &x1, &y1, sparam );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotmg( Order, float& d1, float& d2, float& x1, const float y1,
+ float* sparam ) {
+ cblas_srotmg( cblas_option< Order >::value, &d1, &d2, &x1, &y1, sparam );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotmg( Order, double& d1, double& d2, double& x1, const double y1,
+ double* dparam ) {
+ cblas_drotmg( cblas_option< Order >::value, &d1, &d2, &x1, &y1, dparam );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void rotmg( Order, float& d1, float& d2, float& x1, const float y1,
+ float* sparam ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSrotmg( &d1, &d2, &x1, &y1, sparam );
-#else
- BLAS_SROTMG( &d1, &d2, &x1, &y1, sparam );
-#endif
 }
 
-inline void rotmg( double& d1, double& d2, double& x1, const double y1,
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void rotmg( Order, double& d1, double& d2, double& x1, const double y1,
         double* dparam ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_drotmg( &d1, &d2, &x1, &y1, dparam );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDrotmg( &d1, &d2, &x1, &y1, dparam );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void rotmg( Order, float& d1, float& d2, float& x1, const float y1,
+ float* sparam ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SROTMG( &d1, &d2, &x1, &y1, sparam );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void rotmg( Order, double& d1, double& d2, double& x1, const double y1,
+ double* dparam ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DROTMG( &d1, &d2, &x1, &y1, dparam );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to rotmg.
+//
+template< typename Value >
 struct rotmg_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorDPARAM >
     static return_type invoke( real_type& d1, real_type& d2, real_type& x1,
             const real_type y1, VectorDPARAM& dparam ) {
- detail::rotmg( d1, d2, x1, y1, traits::vector_storage(dparam) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorDPARAM >::value ) );
+
+ detail::rotmg( d1, d2, x1, y1, begin_value(dparam) );
     }
 };
 
-// generic template function to call rotmg
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the rotmg_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * typename remove_imaginary< typename value< VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
+template< typename VectorDPARAM >
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
+}
+
+//
+// Overloaded function for rotmg. Its overload differs for
+// * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type&
+ // * const VectorDPARAM&
+//
 template< typename VectorDPARAM >
-inline typename rotmg_impl< typename traits::vector_traits<
- VectorDPARAM >::value_type >::return_type
-rotmg( typename traits::type_traits< typename traits::vector_traits<
- VectorDPARAM >::value_type >::real_type& d1,
- typename traits::type_traits< typename traits::vector_traits<
- VectorDPARAM >::value_type >::real_type& d2,
- typename traits::type_traits< typename traits::vector_traits<
- VectorDPARAM >::value_type >::real_type& x1,
- const typename traits::type_traits< typename traits::vector_traits<
- VectorDPARAM >::value_type >::real_type y1, VectorDPARAM& dparam ) {
- typedef typename traits::vector_traits<
- VectorDPARAM >::value_type value_type;
- rotmg_impl< value_type >::invoke( d1, d2, x1, y1, dparam );
+inline typename rotmg_impl< typename value<
+ VectorDPARAM >::type >::return_type
+rotmg( const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& d1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type& d2,
+ const typename remove_imaginary< typename value<
+ VectorDPARAM >::type >::type& x1, const typename remove_imaginary<
+ typename value< VectorDPARAM >::type >::type y1,
+ const VectorDPARAM& dparam ) {
+ rotmg_impl< typename value< VectorDPARAM >::type >::invoke( d1, d2,
+ x1, y1, dparam );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/scal.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/scal.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/scal.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,102 +14,243 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SCAL_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SCAL_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void scal( const integer_t n, const float a, const float* x,
- const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sscal( n, a, x, incx );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const float a, float* x,
+ const std::ptrdiff_t incx ) {
+ cblas_sscal( cblas_option< Order >::value, n, a, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const double a, double* x,
+ const std::ptrdiff_t incx ) {
+ cblas_dscal( cblas_option< Order >::value, n, a, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ cblas_cscal( cblas_option< Order >::value, n, &a, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ cblas_zscal( cblas_option< Order >::value, n, &a, x, incx );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const float a, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSscal( n, a, x, incx );
-#else
- BLAS_SSCAL( &n, &a, x, &incx );
-#endif
 }
 
-inline void scal( const integer_t n, const double a, const double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dscal( n, a, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const double a, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDscal( n, a, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCscal( n, a, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasZscal( n, a, x, incx );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const float a, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSCAL( &n, &a, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const double a, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DSCAL( &n, &a, x, &incx );
-#endif
 }
 
-inline void scal( const integer_t n, const traits::complex_f a,
- const traits::complex_f* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cscal( n, traits::void_ptr(&a), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCscal( n, traits::void_ptr(a), traits::void_ptr(x), incx );
-#else
- BLAS_CSCAL( &n, traits::complex_ptr(&a), traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<float> a,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CSCAL( &n, &a, x, &incx );
 }
 
-inline void scal( const integer_t n, const traits::complex_d a,
- const traits::complex_d* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zscal( n, traits::void_ptr(&a), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasZscal( n, traits::void_ptr(a), traits::void_ptr(x), incx );
-#else
- BLAS_ZSCAL( &n, traits::complex_ptr(&a), traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void scal( Order, const std::ptrdiff_t n, const std::complex<double> a,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZSCAL( &n, &a, x, &incx );
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to scal.
+//
+template< typename Value >
 struct scal_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX >
- static return_type invoke( const value_type a, const VectorX& x ) {
- detail::scal( traits::vector_size(x), a,
- traits::vector_storage(x), traits::vector_stride(x) );
+ static return_type invoke( const value_type a, VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+
+ detail::scal( size(x), a, begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call scal
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the scal_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for scal. Its overload differs for
+// * VectorX&
+//
+template< typename VectorX >
+inline typename scal_impl< typename value< VectorX >::type >::return_type
+scal( const typename value< VectorX >::type a, VectorX& x ) {
+ scal_impl< typename value< VectorX >::type >::invoke( a, x );
+}
+
+//
+// Overloaded function for scal. Its overload differs for
+// * const VectorX&
+//
 template< typename VectorX >
-inline typename scal_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-scal( const typename traits::vector_traits< VectorX >::value_type a,
- const VectorX& x ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- scal_impl< value_type >::invoke( a, x );
+inline typename scal_impl< typename value< VectorX >::type >::return_type
+scal( const typename value< VectorX >::type a, const VectorX& x ) {
+ scal_impl< typename value< VectorX >::type >::invoke( a, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/sdot.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/sdot.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/sdot.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,73 +14,139 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SDOT_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SDOT_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline double sdot( const integer_t n, const float* sx, const integer_t incx,
- const float* sy, const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- return cblas_dsdot( n, sx, incx, sy, incy );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double sdot( Order, const std::ptrdiff_t n, const float* sx,
+ const std::ptrdiff_t incx, const float* sy,
+ const std::ptrdiff_t incy ) {
+ return cblas_dsdot( cblas_option< Order >::value, n, sx, incx, sy, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline double sdot( Order, const std::ptrdiff_t n, const float* sx,
+ const std::ptrdiff_t incx, const float* sy,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return // NOT FOUND();
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline double sdot( Order, const std::ptrdiff_t n, const float* sx,
+ const std::ptrdiff_t incx, const float* sy,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     return BLAS_DSDOT( &n, sx, &incx, sy, &incy );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to sdot.
+//
+template< typename Value >
 struct sdot_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef value_type return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorSX, typename VectorSY >
- static return_type invoke( const integer_t n, const VectorSX& sx,
- const integer_t incx, const VectorSY& sy, const integer_t incy ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorSX >::value_type, typename traits::vector_traits<
- VectorSY >::value_type >::value) );
- return detail::sdot( n, traits::vector_storage(sx), incx,
- traits::vector_storage(sy), incy );
+ static return_type invoke( const std::ptrdiff_t n, const VectorSX& sx,
+ const std::ptrdiff_t incx, const VectorSY& sy,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorSX >::type >::type, typename remove_const<
+ typename value< VectorSY >::type >::type >::value) );
+
+ return detail::sdot( n, begin_value(sx), incx, begin_value(sy),
+ incy );
     }
 };
 
-// generic template function to call sdot
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the sdot_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for sdot. Its overload differs for
+//
 template< typename VectorSX, typename VectorSY >
-inline typename sdot_impl< typename traits::vector_traits<
- VectorSX >::value_type >::return_type
-sdot( const integer_t n, const VectorSX& sx, const integer_t incx,
- const VectorSY& sy, const integer_t incy ) {
- typedef typename traits::vector_traits< VectorSX >::value_type value_type;
- return sdot_impl< value_type >::invoke( n, sx, incx, sy, incy );
+inline typename sdot_impl< typename value<
+ VectorSX >::type >::return_type
+sdot( const std::ptrdiff_t n, const VectorSX& sx,
+ const std::ptrdiff_t incx, const VectorSY& sy,
+ const std::ptrdiff_t incy ) {
+ return sdot_impl< typename value< VectorSX >::type >::invoke( n, sx,
+ incx, sy, incy );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/swap.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/swap.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level1/swap.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,107 +14,278 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SWAP_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL1_SWAP_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void swap( const integer_t n, float* x, const integer_t incx, float* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sswap( n, x, incx, y, incy );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ cblas_sswap( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ cblas_dswap( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_cswap( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<double>* x,
+ const std::ptrdiff_t incx, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_zswap( cblas_option< Order >::value, n, x, incx, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSswap( n, x, incx, y, incy );
-#else
- BLAS_SSWAP( &n, x, &incx, y, &incy );
-#endif
 }
 
-inline void swap( const integer_t n, double* x, const integer_t incx,
- double* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dswap( n, x, incx, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDswap( n, x, incx, y, incy );
-#else
- BLAS_DSWAP( &n, x, &incx, y, &incy );
-#endif
 }
 
-inline void swap( const integer_t n, traits::complex_f* x,
- const integer_t incx, traits::complex_f* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cswap( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCswap( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#else
- BLAS_CSWAP( &n, traits::complex_ptr(x), &incx, traits::complex_ptr(y),
- &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCswap( n, x, incx, y, incy );
 }
 
-inline void swap( const integer_t n, traits::complex_d* x,
- const integer_t incx, traits::complex_d* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zswap( n, traits::void_ptr(x), incx, traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<double>* x,
+ const std::ptrdiff_t incx, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZSWAP( &n, traits::complex_ptr(x), &incx, traits::complex_ptr(y),
- &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, float* x,
+ const std::ptrdiff_t incx, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSWAP( &n, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, double* x,
+ const std::ptrdiff_t incx, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSWAP( &n, x, &incx, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<float>* x,
+ const std::ptrdiff_t incx, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CSWAP( &n, x, &incx, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void swap( Order, const std::ptrdiff_t n, std::complex<double>* x,
+ const std::ptrdiff_t incx, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZSWAP( &n, x, &incx, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to swap.
+//
+template< typename Value >
 struct swap_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY >
     static return_type invoke( VectorX& x, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::swap( traits::vector_size(x), traits::vector_storage(x),
- traits::vector_stride(x), traits::vector_storage(y),
- traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+
+ detail::swap( size(x), begin_value(x), stride(x),
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call swap
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the swap_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for swap. Its overload differs for
+// * VectorX&
+ // * VectorY&
+//
 template< typename VectorX, typename VectorY >
-inline typename swap_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
+inline typename swap_impl< typename value< VectorX >::type >::return_type
 swap( VectorX& x, VectorY& y ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- swap_impl< value_type >::invoke( x, y );
+ swap_impl< typename value< VectorX >::type >::invoke( x, y );
+}
+
+//
+// Overloaded function for swap. Its overload differs for
+// * const VectorX&
+ // * VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename swap_impl< typename value< VectorX >::type >::return_type
+swap( const VectorX& x, VectorY& y ) {
+ swap_impl< typename value< VectorX >::type >::invoke( x, y );
+}
+
+//
+// Overloaded function for swap. Its overload differs for
+// * VectorX&
+ // * const VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename swap_impl< typename value< VectorX >::type >::return_type
+swap( VectorX& x, const VectorY& y ) {
+ swap_impl< typename value< VectorX >::type >::invoke( x, y );
+}
+
+//
+// Overloaded function for swap. Its overload differs for
+// * const VectorX&
+ // * const VectorY&
+//
+template< typename VectorX, typename VectorY >
+inline typename swap_impl< typename value< VectorX >::type >::return_type
+swap( const VectorX& x, const VectorY& y ) {
+ swap_impl< typename value< VectorX >::type >::invoke( x, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gbmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gbmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gbmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,151 +14,323 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GBMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GBMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void gbmv( const char trans, const integer_t m, const integer_t n,
- const integer_t kl, const integer_t ku, const float alpha,
- const float* a, const integer_t lda, const float* x,
- const integer_t incx, const float beta, float* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sgbmv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ cblas_sgbmv( cblas_option< Order >::value, cblas_option< Trans >::value,
             m, n, kl, ku, alpha, a, lda, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSgbmv( trans, m, n, kl, ku, alpha, a, lda, x, incx, beta, y, incy );
-#else
- BLAS_SGBMV( &trans, &m, &n, &kl, &ku, &alpha, a, &lda, x, &incx, &beta, y,
- &incy );
-#endif
 }
 
-inline void gbmv( const char trans, const integer_t m, const integer_t n,
- const integer_t kl, const integer_t ku, const double alpha,
- const double* a, const integer_t lda, const double* x,
- const integer_t incx, const double beta, double* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dgbmv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ cblas_dgbmv( cblas_option< Order >::value, cblas_option< Trans >::value,
             m, n, kl, ku, alpha, a, lda, x, incx, beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_cgbmv( cblas_option< Order >::value, cblas_option< Trans >::value,
+ m, n, kl, ku, &alpha, a, lda, x, incx, &beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_zgbmv( cblas_option< Order >::value, cblas_option< Trans >::value,
+ m, n, kl, ku, &alpha, a, lda, x, incx, &beta, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSgbmv( blas_option< Trans >::value, m, n, kl, ku, alpha, a, lda, x,
+ incx, beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DGBMV( &trans, &m, &n, &kl, &ku, &alpha, a, &lda, x, &incx, &beta, y,
- &incy );
-#endif
 }
 
-inline void gbmv( const char trans, const integer_t m, const integer_t n,
- const integer_t kl, const integer_t ku, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* x, const integer_t incx,
- const traits::complex_f beta, traits::complex_f* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cgbmv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, kl, ku, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCgbmv( trans, m, n, kl, ku, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(x), incx,
- traits::void_ptr(beta), traits::void_ptr(y), incy );
-#else
- BLAS_CGBMV( &trans, &m, &n, &kl, &ku, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCgbmv( blas_option< Trans >::value, m, n, kl, ku, alpha, a, lda, x,
+ incx, beta, y, incy );
 }
 
-inline void gbmv( const char trans, const integer_t m, const integer_t n,
- const integer_t kl, const integer_t ku, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* x, const integer_t incx,
- const traits::complex_d beta, traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zgbmv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, kl, ku, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZGBMV( &trans, &m, &n, &kl, &ku, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SGBMV( &blas_option< Trans >::value, &m, &n, &kl, &ku, &alpha, a,
+ &lda, x, &incx, &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DGBMV( &blas_option< Trans >::value, &m, &n, &kl, &ku, &alpha, a,
+ &lda, x, &incx, &beta, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CGBMV( &blas_option< Trans >::value, &m, &n, &kl, &ku, &alpha, a,
+ &lda, x, &incx, &beta, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gbmv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZGBMV( &blas_option< Trans >::value, &m, &n, &kl, &ku, &alpha, a,
+ &lda, x, &incx, &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to gbmv.
+//
+template< typename Value >
 struct gbmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
- static return_type invoke( const char trans, const integer_t kl,
- const integer_t ku, const value_type alpha, const MatrixA& a,
+ static return_type invoke( const std::ptrdiff_t kl,
+ const std::ptrdiff_t ku, const value_type alpha, const MatrixA& a,
             const VectorX& x, const value_type beta, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::gbmv( trans, traits::matrix_num_rows(a),
- traits::matrix_num_columns(a), kl, ku, alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::gbmv( order(), trans(), size_row_op(a, trans()),
+ size_column_op(a, trans()), kl, ku, alpha, begin_value(a),
+ stride_major(a), begin_value(x), stride(x), beta,
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call gbmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the gbmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for gbmv. Its overload differs for
+// * VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename gbmv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-gbmv( const char trans, const integer_t kl, const integer_t ku,
- const typename traits::matrix_traits< MatrixA >::value_type alpha,
- const MatrixA& a, const VectorX& x,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
+inline typename gbmv_impl< typename value< MatrixA >::type >::return_type
+gbmv( const std::ptrdiff_t kl, const std::ptrdiff_t ku,
+ const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
         VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- gbmv_impl< value_type >::invoke( trans, kl, ku, alpha, a, x, beta,
- y );
+ gbmv_impl< typename value< MatrixA >::type >::invoke( kl, ku, alpha,
+ a, x, beta, y );
+}
+
+//
+// Overloaded function for gbmv. Its overload differs for
+// * const VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename gbmv_impl< typename value< MatrixA >::type >::return_type
+gbmv( const std::ptrdiff_t kl, const std::ptrdiff_t ku,
+ const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
+ const VectorY& y ) {
+ gbmv_impl< typename value< MatrixA >::type >::invoke( kl, ku, alpha,
+ a, x, beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gemv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gemv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gemv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,114 +14,252 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GEMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GEMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void gemv( const char trans, const integer_t m, const integer_t n,
- const float alpha, const float* a, const integer_t lda,
- const float* x, const integer_t incx, const float beta, float* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sgemv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ cblas_sgemv( cblas_option< Order >::value, cblas_option< Trans >::value,
             m, n, alpha, a, lda, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSgemv( trans, m, n, alpha, a, lda, x, incx, beta, y, incy );
-#else
- BLAS_SGEMV( &trans, &m, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
 }
 
-inline void gemv( const char trans, const integer_t m, const integer_t n,
- const double alpha, const double* a, const integer_t lda,
- const double* x, const integer_t incx, const double beta, double* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dgemv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ cblas_dgemv( cblas_option< Order >::value, cblas_option< Trans >::value,
             m, n, alpha, a, lda, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDgemv( trans, m, n, alpha, a, lda, x, incx, beta, y, incy );
-#else
- BLAS_DGEMV( &trans, &m, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
 }
 
-inline void gemv( const char trans, const integer_t m, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* a,
- const integer_t lda, const traits::complex_f* x, const integer_t incx,
- const traits::complex_f beta, traits::complex_f* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cgemv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCgemv( trans, m, n, traits::void_ptr(alpha), traits::void_ptr(a),
- lda, traits::void_ptr(x), incx, traits::void_ptr(beta),
- traits::void_ptr(y), incy );
-#else
- BLAS_CGEMV( &trans, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_cgemv( cblas_option< Order >::value, cblas_option< Trans >::value,
+ m, n, &alpha, a, lda, x, incx, &beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_zgemv( cblas_option< Order >::value, cblas_option< Trans >::value,
+ m, n, &alpha, a, lda, x, incx, &beta, y, incy );
 }
 
-inline void gemv( const char trans, const integer_t m, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* a,
- const integer_t lda, const traits::complex_d* x, const integer_t incx,
- const traits::complex_d beta, traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zgemv( CblasColMajor,
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasZgemv( trans, m, n, traits::void_ptr(alpha), traits::void_ptr(a),
- lda, traits::void_ptr(x), incx, traits::void_ptr(beta),
- traits::void_ptr(y), incy );
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSgemv( blas_option< Trans >::value, m, n, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDgemv( blas_option< Trans >::value, m, n, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCgemv( blas_option< Trans >::value, m, n, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasZgemv( blas_option< Trans >::value, m, n, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
 #else
- BLAS_ZGEMV( &trans, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SGEMV( &blas_option< Trans >::value, &m, &n, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DGEMV( &blas_option< Trans >::value, &m, &n, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CGEMV( &blas_option< Trans >::value, &m, &n, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename Trans >
+inline void gemv( Order, Trans, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZGEMV( &blas_option< Trans >::value, &m, &n, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to gemv.
+//
+template< typename Value >
 struct gemv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
     // high-level transform typedefs and functions
@@ -131,35 +269,62 @@
         invoke();
     }
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
- static return_type invoke( const char trans, const value_type alpha,
- const MatrixA& a, const VectorX& x, const value_type beta,
- VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::gemv( trans, traits::matrix_num_rows(a),
- traits::matrix_num_columns(a), alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ static return_type invoke( const value_type alpha, const MatrixA& a,
+ const VectorX& x, const value_type beta, VectorY& y ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::gemv( order(), trans(), size_row_op(a, trans()),
+ size_column_op(a, trans()), alpha, begin_value(a),
+ stride_major(a), begin_value(x), stride(x), beta,
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call gemv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the gemv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for gemv. Its overload differs for
+// * VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename gemv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-gemv( const char trans, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const VectorX& x,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
+inline typename gemv_impl< typename value< MatrixA >::type >::return_type
+gemv( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
         VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- gemv_impl< value_type >::invoke( trans, alpha, a, x, beta, y );
+ gemv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
+}
+
+//
+// Overloaded function for gemv. Its overload differs for
+// * const VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename gemv_impl< typename value< MatrixA >::type >::return_type
+gemv( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
+ const VectorY& y ) {
+ gemv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/ger.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/ger.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/ger.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,94 +14,203 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GER_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GER_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void ger( const integer_t m, const integer_t n, const float alpha,
- const float* x, const integer_t incx, const float* y,
- const integer_t incy, float* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sger( CblasColMajor, m, n, alpha, x, incx, y, incy, a, lda );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const float alpha, const float* x, const std::ptrdiff_t incx,
+ const float* y, const std::ptrdiff_t incy, float* a,
+ const std::ptrdiff_t lda ) {
+ cblas_sger( cblas_option< Order >::value, m, n, alpha, x, incx, y, incy,
+ a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const double alpha, const double* x, const std::ptrdiff_t incx,
+ const double* y, const std::ptrdiff_t incy, double* a,
+ const std::ptrdiff_t lda ) {
+ cblas_dger( cblas_option< Order >::value, m, n, alpha, x, incx, y, incy,
+ a, lda );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const float alpha, const float* x, const std::ptrdiff_t incx,
+ const float* y, const std::ptrdiff_t incy, float* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasSger( m, n, alpha, x, incx, y, incy, a, lda );
-#else
- BLAS_SGER( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
-#endif
 }
 
-inline void ger( const integer_t m, const integer_t n, const double alpha,
- const double* x, const integer_t incx, const double* y,
- const integer_t incy, double* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dger( CblasColMajor, m, n, alpha, x, incx, y, incy, a, lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const double alpha, const double* x, const std::ptrdiff_t incx,
+ const double* y, const std::ptrdiff_t incy, double* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     cublasDger( m, n, alpha, x, incx, y, incy, a, lda );
+}
+
 #else
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const float alpha, const float* x, const std::ptrdiff_t incx,
+ const float* y, const std::ptrdiff_t incy, float* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SGER( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order >
+inline void ger( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const double alpha, const double* x, const std::ptrdiff_t incx,
+ const double* y, const std::ptrdiff_t incy, double* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     BLAS_DGER( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
-#endif
 }
 
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to ger.
+//
+template< typename Value >
 struct ger_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixA >
     static return_type invoke( const real_type alpha, const VectorX& x,
             const VectorY& y, MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::ger( traits::matrix_num_rows(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ detail::ger( order(), size_row(a), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call ger
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the ger_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for ger. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename VectorY, typename MatrixA >
+inline typename ger_impl< typename value< VectorX >::type >::return_type
+ger( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ MatrixA& a ) {
+ ger_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
+}
+
+//
+// Overloaded function for ger. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename VectorY, typename MatrixA >
-inline typename ger_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-ger( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- const VectorY& y, MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- ger_impl< value_type >::invoke( alpha, x, y, a );
+inline typename ger_impl< typename value< VectorX >::type >::return_type
+ger( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ const MatrixA& a ) {
+ ger_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gerc.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gerc.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/gerc.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,103 +14,207 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GERC_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GERC_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void gerc( const integer_t m, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy, traits::complex_f* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cgerc( CblasColMajor, m, n, traits::void_ptr(&alpha),
- traits::void_ptr(x), incx, traits::void_ptr(y), incy,
- traits::void_ptr(a), lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCgerc( m, n, traits::void_ptr(alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(a), lda );
-#else
- BLAS_CGERC( &m, &n, traits::complex_ptr(&alpha), traits::complex_ptr(x),
- &incx, traits::complex_ptr(y), &incy, traits::complex_ptr(a),
- &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_cgerc( cblas_option< Order >::value, m, n, &alpha, x, incx, y, incy,
+ a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_zgerc( cblas_option< Order >::value, m, n, &alpha, x, incx, y, incy,
+ a, lda );
 }
 
-inline void gerc( const integer_t m, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy, traits::complex_d* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zgerc( CblasColMajor, m, n, traits::void_ptr(&alpha),
- traits::void_ptr(x), incx, traits::void_ptr(y), incy,
- traits::void_ptr(a), lda );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCgerc( m, n, alpha, x, incx, y, incy, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZGERC( &m, &n, traits::complex_ptr(&alpha), traits::complex_ptr(x),
- &incx, traits::complex_ptr(y), &incy, traits::complex_ptr(a),
- &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CGERC( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void gerc( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZGERC( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to gerc.
+//
+template< typename Value >
 struct gerc_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixA >
     static return_type invoke( const value_type alpha, const VectorX& x,
             const VectorY& y, MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::gerc( traits::matrix_num_rows(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ detail::gerc( order(), size_row(a), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call gerc
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the gerc_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for gerc. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename VectorY, typename MatrixA >
+inline typename gerc_impl< typename value< VectorX >::type >::return_type
+gerc( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, MatrixA& a ) {
+ gerc_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
+}
+
+//
+// Overloaded function for gerc. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename VectorY, typename MatrixA >
-inline typename gerc_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-gerc( const typename traits::vector_traits< VectorX >::value_type alpha,
- const VectorX& x, const VectorY& y, MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- gerc_impl< value_type >::invoke( alpha, x, y, a );
+inline typename gerc_impl< typename value< VectorX >::type >::return_type
+gerc( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, const MatrixA& a ) {
+ gerc_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/geru.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/geru.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/geru.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,103 +14,207 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GERU_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_GERU_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void geru( const integer_t m, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy, traits::complex_f* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cgeru( CblasColMajor, m, n, traits::void_ptr(&alpha),
- traits::void_ptr(x), incx, traits::void_ptr(y), incy,
- traits::void_ptr(a), lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCgeru( m, n, traits::void_ptr(alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(a), lda );
-#else
- BLAS_CGERU( &m, &n, traits::complex_ptr(&alpha), traits::complex_ptr(x),
- &incx, traits::complex_ptr(y), &incy, traits::complex_ptr(a),
- &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_cgeru( cblas_option< Order >::value, m, n, &alpha, x, incx, y, incy,
+ a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_zgeru( cblas_option< Order >::value, m, n, &alpha, x, incx, y, incy,
+ a, lda );
 }
 
-inline void geru( const integer_t m, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy, traits::complex_d* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zgeru( CblasColMajor, m, n, traits::void_ptr(&alpha),
- traits::void_ptr(x), incx, traits::void_ptr(y), incy,
- traits::void_ptr(a), lda );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCgeru( m, n, alpha, x, incx, y, incy, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZGERU( &m, &n, traits::complex_ptr(&alpha), traits::complex_ptr(x),
- &incx, traits::complex_ptr(y), &incy, traits::complex_ptr(a),
- &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CGERU( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order >
+inline void geru( Order, const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZGERU( &m, &n, &alpha, x, &incx, y, &incy, a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to geru.
+//
+template< typename Value >
 struct geru_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixA >
     static return_type invoke( const value_type alpha, const VectorX& x,
             const VectorY& y, MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::geru( traits::matrix_num_rows(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ detail::geru( order(), size_row(a), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call geru
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the geru_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for geru. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename VectorY, typename MatrixA >
+inline typename geru_impl< typename value< VectorX >::type >::return_type
+geru( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, MatrixA& a ) {
+ geru_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
+}
+
+//
+// Overloaded function for geru. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename VectorY, typename MatrixA >
-inline typename geru_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-geru( const typename traits::vector_traits< VectorX >::value_type alpha,
- const VectorX& x, const VectorY& y, MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- geru_impl< value_type >::invoke( alpha, x, y, a );
+inline typename geru_impl< typename value< VectorX >::type >::return_type
+geru( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, const MatrixA& a ) {
+ geru_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hbmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hbmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hbmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,111 +14,215 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HBMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HBMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hbmv( const char uplo, const integer_t n, const integer_t k,
- const traits::complex_f alpha, const traits::complex_f* a,
- const integer_t lda, const traits::complex_f* x, const integer_t incx,
- const traits::complex_f beta, traits::complex_f* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChbmv( uplo, n, k, traits::void_ptr(alpha), traits::void_ptr(a),
- lda, traits::void_ptr(x), incx, traits::void_ptr(beta),
- traits::void_ptr(y), incy );
-#else
- BLAS_CHBMV( &uplo, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ cblas_chbmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ k, &alpha, a, lda, x, incx, &beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ cblas_zhbmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ k, &alpha, a, lda, x, incx, &beta, y, incy );
 }
 
-inline void hbmv( const char uplo, const integer_t n, const integer_t k,
- const traits::complex_d alpha, const traits::complex_d* a,
- const integer_t lda, const traits::complex_d* x, const integer_t incx,
- const traits::complex_d beta, traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChbmv( blas_option< UpLo >::value, n, k, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHBMV( &uplo, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHBMV( &blas_option< UpLo >::value, &n, &k, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHBMV( &blas_option< UpLo >::value, &n, &k, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hbmv.
+//
+template< typename Value >
 struct hbmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
- static return_type invoke( const integer_t k, const value_type alpha,
+ static return_type invoke( const std::ptrdiff_t k, const value_type alpha,
             const MatrixA& a, const VectorX& x, const value_type beta,
             VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::hbmv( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), k, alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::hbmv( order(), uplo(), size_column(a), k, alpha,
+ begin_value(a), stride_major(a), begin_value(x), stride(x),
+ beta, begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call hbmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hbmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hbmv. Its overload differs for
+// * VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename hbmv_impl< typename value< MatrixA >::type >::return_type
+hbmv( const std::ptrdiff_t k, const typename value<
+ MatrixA >::type alpha, const MatrixA& a, const VectorX& x,
+ const typename value< MatrixA >::type beta, VectorY& y ) {
+ hbmv_impl< typename value< MatrixA >::type >::invoke( k, alpha, a,
+ x, beta, y );
+}
+
+//
+// Overloaded function for hbmv. Its overload differs for
+// * const VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename hbmv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-hbmv( const integer_t k, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const VectorX& x,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
- VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- hbmv_impl< value_type >::invoke( k, alpha, a, x, beta, y );
+inline typename hbmv_impl< typename value< MatrixA >::type >::return_type
+hbmv( const std::ptrdiff_t k, const typename value<
+ MatrixA >::type alpha, const MatrixA& a, const VectorX& x,
+ const typename value< MatrixA >::type beta, const VectorY& y ) {
+ hbmv_impl< typename value< MatrixA >::type >::invoke( k, alpha, a,
+ x, beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hemv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hemv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hemv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,110 +14,214 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HEMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HEMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hemv( const char uplo, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* a,
- const integer_t lda, const traits::complex_f* x, const integer_t incx,
- const traits::complex_f beta, traits::complex_f* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chemv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChemv( uplo, n, traits::void_ptr(alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(beta),
- traits::void_ptr(y), incy );
-#else
- BLAS_CHEMV( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ cblas_chemv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, a, lda, x, incx, &beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ cblas_zhemv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, a, lda, x, incx, &beta, y, incy );
 }
 
-inline void hemv( const char uplo, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* a,
- const integer_t lda, const traits::complex_d* x, const integer_t incx,
- const traits::complex_d beta, traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhemv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChemv( blas_option< UpLo >::value, n, alpha, a, lda, x, incx, beta,
+ y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHEMV( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float> beta,
+ std::complex<float>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHEMV( &blas_option< UpLo >::value, &n, &alpha, a, &lda, x, &incx,
+ &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double> beta,
+ std::complex<double>* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHEMV( &blas_option< UpLo >::value, &n, &alpha, a, &lda, x, &incx,
+ &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hemv.
+//
+template< typename Value >
 struct hemv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
     static return_type invoke( const value_type alpha, const MatrixA& a,
             const VectorX& x, const value_type beta, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::hemv( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::hemv( order(), uplo(), size_column(a), alpha,
+ begin_value(a), stride_major(a), begin_value(x), stride(x),
+ beta, begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call hemv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hemv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hemv. Its overload differs for
+// * VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename hemv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-hemv( const typename traits::matrix_traits< MatrixA >::value_type alpha,
- const MatrixA& a, const VectorX& x,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
+inline typename hemv_impl< typename value< MatrixA >::type >::return_type
+hemv( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
         VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- hemv_impl< value_type >::invoke( alpha, a, x, beta, y );
+ hemv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
+}
+
+//
+// Overloaded function for hemv. Its overload differs for
+// * const VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename hemv_impl< typename value< MatrixA >::type >::return_type
+hemv( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename value< MatrixA >::type beta,
+ const VectorY& y ) {
+ hemv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,95 +14,191 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HER_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HER_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void her( const char uplo, const integer_t n, const float alpha,
- const traits::complex_f* x, const integer_t incx,
- traits::complex_f* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cher( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- alpha, traits::void_ptr(x), incx, traits::void_ptr(a), lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCher( uplo, n, alpha, traits::void_ptr(x), incx,
- traits::void_ptr(a), lda );
-#else
- BLAS_CHER( &uplo, &n, &alpha, traits::complex_ptr(x), &incx,
- traits::complex_ptr(a), &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* a, const std::ptrdiff_t lda ) {
+ cblas_cher( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ alpha, x, incx, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* a, const std::ptrdiff_t lda ) {
+ cblas_zher( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ alpha, x, incx, a, lda );
 }
 
-inline void her( const char uplo, const integer_t n, const double alpha,
- const traits::complex_d* x, const integer_t incx,
- traits::complex_d* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zher( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- alpha, traits::void_ptr(x), incx, traits::void_ptr(a), lda );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCher( blas_option< UpLo >::value, n, alpha, x, incx, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHER( &uplo, &n, &alpha, traits::complex_ptr(x), &incx,
- traits::complex_ptr(a), &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHER( &blas_option< UpLo >::value, &n, &alpha, x, &incx, a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHER( &blas_option< UpLo >::value, &n, &alpha, x, &incx, a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to her.
+//
+template< typename Value >
 struct her_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename MatrixA >
     static return_type invoke( const real_type alpha, const VectorX& x,
             MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::her( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::her( order(), uplo(), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call her
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the her_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for her. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename MatrixA >
+inline typename her_impl< typename value< VectorX >::type >::return_type
+her( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, MatrixA& a ) {
+ her_impl< typename value< VectorX >::type >::invoke( alpha, x, a );
+}
+
+//
+// Overloaded function for her. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename MatrixA >
-inline typename her_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-her( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- her_impl< value_type >::invoke( alpha, x, a );
+inline typename her_impl< typename value< VectorX >::type >::return_type
+her( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const MatrixA& a ) {
+ her_impl< typename value< VectorX >::type >::invoke( alpha, x, a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her2.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her2.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/her2.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,103 +14,212 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HER2_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HER2_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void her2( const char uplo, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy, traits::complex_f* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cher2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(a), lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCher2( uplo, n, traits::void_ptr(alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(a), lda );
-#else
- BLAS_CHER2( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(x), &incx, traits::complex_ptr(y), &incy,
- traits::complex_ptr(a), &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_cher2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, x, incx, y, incy, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ cblas_zher2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, x, incx, y, incy, a, lda );
 }
 
-inline void her2( const char uplo, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy, traits::complex_d* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zher2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(a), lda );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCher2( blas_option< UpLo >::value, n, alpha, x, incx, y, incy, a,
+ lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHER2( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(x), &incx, traits::complex_ptr(y), &incy,
- traits::complex_ptr(a), &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHER2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void her2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHER2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to her2.
+//
+template< typename Value >
 struct her2_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixA >
     static return_type invoke( const value_type alpha, const VectorX& x,
             const VectorY& y, MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::her2( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::her2( order(), uplo(), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call her2
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the her2_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for her2. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename VectorY, typename MatrixA >
+inline typename her2_impl< typename value< VectorX >::type >::return_type
+her2( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, MatrixA& a ) {
+ her2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
+}
+
+//
+// Overloaded function for her2. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename VectorY, typename MatrixA >
-inline typename her2_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-her2( const typename traits::vector_traits< VectorX >::value_type alpha,
- const VectorX& x, const VectorY& y, MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- her2_impl< value_type >::invoke( alpha, x, y, a );
+inline typename her2_impl< typename value< VectorX >::type >::return_type
+her2( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, const MatrixA& a ) {
+ her2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,110 +14,216 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hpmv( const char uplo, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* ap,
- const traits::complex_f* x, const integer_t incx,
- const traits::complex_f beta, traits::complex_f* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(ap),
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChpmv( uplo, n, traits::void_ptr(alpha), traits::void_ptr(ap),
- traits::void_ptr(x), incx, traits::void_ptr(beta),
- traits::void_ptr(y), incy );
-#else
- BLAS_CHPMV( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(ap), traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* ap,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_chpmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, ap, x, incx, &beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* ap,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ cblas_zhpmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, ap, x, incx, &beta, y, incy );
 }
 
-inline void hpmv( const char uplo, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* ap,
- const traits::complex_d* x, const integer_t incx,
- const traits::complex_d beta, traits::complex_d* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(ap),
- traits::void_ptr(x), incx, traits::void_ptr(&beta),
- traits::void_ptr(y), incy );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* ap,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChpmv( blas_option< UpLo >::value, n, alpha, ap, x, incx, beta, y,
+ incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* ap,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHPMV( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(ap), traits::complex_ptr(x), &incx,
- traits::complex_ptr(&beta), traits::complex_ptr(y), &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* ap,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ const std::complex<float> beta, std::complex<float>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHPMV( &blas_option< UpLo >::value, &n, &alpha, ap, x, &incx, &beta,
+ y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpmv( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* ap,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ const std::complex<double> beta, std::complex<double>* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHPMV( &blas_option< UpLo >::value, &n, &alpha, ap, x, &incx, &beta,
+ y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hpmv.
+//
+template< typename Value >
 struct hpmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixAP, typename VectorX, typename VectorY >
     static return_type invoke( const value_type alpha, const MatrixAP& ap,
             const VectorX& x, const value_type beta, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::hpmv( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::matrix_storage(ap), traits::vector_storage(x),
- traits::vector_stride(x), beta, traits::vector_storage(y),
- traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::hpmv( order(), uplo(), size_column(ap), alpha,
+ begin_value(ap), begin_value(x), stride(x), beta,
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call hpmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hpmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hpmv. Its overload differs for
+// * VectorY&
+//
 template< typename MatrixAP, typename VectorX, typename VectorY >
-inline typename hpmv_impl< typename traits::matrix_traits<
- MatrixAP >::value_type >::return_type
-hpmv( const typename traits::matrix_traits<
- MatrixAP >::value_type alpha, const MatrixAP& ap, const VectorX& x,
- const typename traits::matrix_traits< MatrixAP >::value_type beta,
+inline typename hpmv_impl< typename value<
+ MatrixAP >::type >::return_type
+hpmv( const typename value< MatrixAP >::type alpha, const MatrixAP& ap,
+ const VectorX& x, const typename value< MatrixAP >::type beta,
         VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixAP >::value_type value_type;
- hpmv_impl< value_type >::invoke( alpha, ap, x, beta, y );
+ hpmv_impl< typename value< MatrixAP >::type >::invoke( alpha, ap, x,
+ beta, y );
+}
+
+//
+// Overloaded function for hpmv. Its overload differs for
+// * const VectorY&
+//
+template< typename MatrixAP, typename VectorX, typename VectorY >
+inline typename hpmv_impl< typename value<
+ MatrixAP >::type >::return_type
+hpmv( const typename value< MatrixAP >::type alpha, const MatrixAP& ap,
+ const VectorX& x, const typename value< MatrixAP >::type beta,
+ const VectorY& y ) {
+ hpmv_impl< typename value< MatrixAP >::type >::invoke( alpha, ap, x,
+ beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,95 +14,191 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPR_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPR_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hpr( const char uplo, const integer_t n, const float alpha,
- const traits::complex_f* x, const integer_t incx,
- traits::complex_f* ap ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chpr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- alpha, traits::void_ptr(x), incx, traits::void_ptr(ap) );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChpr( uplo, n, alpha, traits::void_ptr(x), incx,
- traits::void_ptr(ap) );
-#else
- BLAS_CHPR( &uplo, &n, &alpha, traits::complex_ptr(x), &incx,
- traits::complex_ptr(ap) );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* ap ) {
+ cblas_chpr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ alpha, x, incx, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* ap ) {
+ cblas_zhpr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ alpha, x, incx, ap );
 }
 
-inline void hpr( const char uplo, const integer_t n, const double alpha,
- const traits::complex_d* x, const integer_t incx,
- traits::complex_d* ap ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhpr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- alpha, traits::void_ptr(x), incx, traits::void_ptr(ap) );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChpr( blas_option< UpLo >::value, n, alpha, x, incx, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHPR( &uplo, &n, &alpha, traits::complex_ptr(x), &incx,
- traits::complex_ptr(ap) );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const std::complex<float>* x, const std::ptrdiff_t incx,
+ std::complex<float>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHPR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, ap );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const std::complex<double>* x, const std::ptrdiff_t incx,
+ std::complex<double>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHPR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, ap );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hpr.
+//
+template< typename Value >
 struct hpr_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename MatrixAP >
     static return_type invoke( const real_type alpha, const VectorX& x,
             MatrixAP& ap ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixAP >::value_type >::value) );
- detail::hpr( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::matrix_storage(ap) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixAP >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixAP >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::hpr( order(), uplo(), size_column(ap), alpha,
+ begin_value(x), stride(x), begin_value(ap) );
     }
 };
 
-// generic template function to call hpr
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hpr_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hpr. Its overload differs for
+// * MatrixAP&
+//
+template< typename VectorX, typename MatrixAP >
+inline typename hpr_impl< typename value< VectorX >::type >::return_type
+hpr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, MatrixAP& ap ) {
+ hpr_impl< typename value< VectorX >::type >::invoke( alpha, x, ap );
+}
+
+//
+// Overloaded function for hpr. Its overload differs for
+// * const MatrixAP&
+//
 template< typename VectorX, typename MatrixAP >
-inline typename hpr_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-hpr( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- MatrixAP& ap ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- hpr_impl< value_type >::invoke( alpha, x, ap );
+inline typename hpr_impl< typename value< VectorX >::type >::return_type
+hpr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const MatrixAP& ap ) {
+ hpr_impl< typename value< VectorX >::type >::invoke( alpha, x, ap );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr2.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr2.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/hpr2.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,103 +14,205 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPR2_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_HPR2_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hpr2( const char uplo, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* x,
- const integer_t incx, const traits::complex_f* y,
- const integer_t incy, traits::complex_f* ap ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chpr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(ap) );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChpr2( uplo, n, traits::void_ptr(alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(ap) );
-#else
- BLAS_CHPR2( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(x), &incx, traits::complex_ptr(y), &incy,
- traits::complex_ptr(ap) );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* ap ) {
+ cblas_chpr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, x, incx, y, incy, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* ap ) {
+ cblas_zhpr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
+ &alpha, x, incx, y, incy, ap );
 }
 
-inline void hpr2( const char uplo, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* x,
- const integer_t incx, const traits::complex_d* y,
- const integer_t incy, traits::complex_d* ap ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhpr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
- traits::void_ptr(&alpha), traits::void_ptr(x), incx,
- traits::void_ptr(y), incy, traits::void_ptr(ap) );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChpr2( blas_option< UpLo >::value, n, alpha, x, incx, y, incy, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHPR2( &uplo, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(x), &incx, traits::complex_ptr(y), &incy,
- traits::complex_ptr(ap) );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* x,
+ const std::ptrdiff_t incx, const std::complex<float>* y,
+ const std::ptrdiff_t incy, std::complex<float>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHPR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ ap );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hpr2( Order, UpLo, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* x,
+ const std::ptrdiff_t incx, const std::complex<double>* y,
+ const std::ptrdiff_t incy, std::complex<double>* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHPR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ ap );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hpr2.
+//
+template< typename Value >
 struct hpr2_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixAP >
     static return_type invoke( const value_type alpha, const VectorX& x,
             const VectorY& y, MatrixAP& ap ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixAP >::value_type >::value) );
- detail::hpr2( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(ap) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixAP >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixAP >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::hpr2( order(), uplo(), size_column(ap), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(ap) );
     }
 };
 
-// generic template function to call hpr2
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hpr2_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hpr2. Its overload differs for
+// * MatrixAP&
+//
+template< typename VectorX, typename VectorY, typename MatrixAP >
+inline typename hpr2_impl< typename value< VectorX >::type >::return_type
+hpr2( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, MatrixAP& ap ) {
+ hpr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ ap );
+}
+
+//
+// Overloaded function for hpr2. Its overload differs for
+// * const MatrixAP&
+//
 template< typename VectorX, typename VectorY, typename MatrixAP >
-inline typename hpr2_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-hpr2( const typename traits::vector_traits< VectorX >::value_type alpha,
- const VectorX& x, const VectorY& y, MatrixAP& ap ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- hpr2_impl< value_type >::invoke( alpha, x, y, ap );
+inline typename hpr2_impl< typename value< VectorX >::type >::return_type
+hpr2( const typename value< VectorX >::type alpha, const VectorX& x,
+ const VectorY& y, const MatrixAP& ap ) {
+ hpr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ ap );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/sbmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/sbmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/sbmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,101 +14,211 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SBMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SBMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void sbmv( const char uplo, const integer_t n, const integer_t k,
- const float alpha, const float* a, const integer_t lda,
- const float* x, const integer_t incx, const float beta, float* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const float alpha, const float* a, const std::ptrdiff_t lda,
+ const float* x, const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ cblas_ssbmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             k, alpha, a, lda, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsbmv( uplo, n, k, alpha, a, lda, x, incx, beta, y, incy );
-#else
- BLAS_SSBMV( &uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
 }
 
-inline void sbmv( const char uplo, const integer_t n, const integer_t k,
- const double alpha, const double* a, const integer_t lda,
- const double* x, const integer_t incx, const double beta, double* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const double alpha, const double* a, const std::ptrdiff_t lda,
+ const double* x, const std::ptrdiff_t incx, const double beta,
+ double* y, const std::ptrdiff_t incy ) {
+ cblas_dsbmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             k, alpha, a, lda, x, incx, beta, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const float alpha, const float* a, const std::ptrdiff_t lda,
+ const float* x, const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsbmv( blas_option< UpLo >::value, n, k, alpha, a, lda, x, incx,
+ beta, y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const double alpha, const double* a, const std::ptrdiff_t lda,
+ const double* x, const std::ptrdiff_t incx, const double beta,
+ double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSBMV( &uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const float alpha, const float* a, const std::ptrdiff_t lda,
+ const float* x, const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSBMV( &blas_option< UpLo >::value, &n, &k, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void sbmv( Order, UpLo, const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const double alpha, const double* a, const std::ptrdiff_t lda,
+ const double* x, const std::ptrdiff_t incx, const double beta,
+ double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSBMV( &blas_option< UpLo >::value, &n, &k, &alpha, a, &lda, x,
+ &incx, &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to sbmv.
+//
+template< typename Value >
 struct sbmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
- static return_type invoke( const integer_t k, const real_type alpha,
+ static return_type invoke( const std::ptrdiff_t k, const real_type alpha,
             const MatrixA& a, const VectorX& x, const real_type beta,
             VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::sbmv( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), k, alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::sbmv( order(), uplo(), size_column(a), k, alpha,
+ begin_value(a), stride_major(a), begin_value(x), stride(x),
+ beta, begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call sbmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the sbmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for sbmv. Its overload differs for
+// * VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename sbmv_impl< typename value< MatrixA >::type >::return_type
+sbmv( const std::ptrdiff_t k, const typename remove_imaginary<
+ typename value< MatrixA >::type >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, VectorY& y ) {
+ sbmv_impl< typename value< MatrixA >::type >::invoke( k, alpha, a,
+ x, beta, y );
+}
+
+//
+// Overloaded function for sbmv. Its overload differs for
+// * const VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename sbmv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-sbmv( const integer_t k, const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixA >::value_type >::real_type alpha, const MatrixA& a,
- const VectorX& x, const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixA >::value_type >::real_type beta, VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- sbmv_impl< value_type >::invoke( k, alpha, a, x, beta, y );
+inline typename sbmv_impl< typename value< MatrixA >::type >::return_type
+sbmv( const std::ptrdiff_t k, const typename remove_imaginary<
+ typename value< MatrixA >::type >::type alpha, const MatrixA& a,
+ const VectorX& x, const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, const VectorY& y ) {
+ sbmv_impl< typename value< MatrixA >::type >::invoke( k, alpha, a,
+ x, beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,98 +14,206 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void spmv( const char uplo, const integer_t n, const float alpha,
- const float* ap, const float* x, const integer_t incx,
- const float beta, float* y, const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sspmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* ap, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ cblas_sspmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, ap, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSspmv( uplo, n, alpha, ap, x, incx, beta, y, incy );
-#else
- BLAS_SSPMV( &uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy );
-#endif
 }
 
-inline void spmv( const char uplo, const integer_t n, const double alpha,
- const double* ap, const double* x, const integer_t incx,
- const double beta, double* y, const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dspmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* ap, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ cblas_dspmv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, ap, x, incx, beta, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* ap, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSspmv( blas_option< UpLo >::value, n, alpha, ap, x, incx, beta, y,
+ incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* ap, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSPMV( &uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* ap, const float* x, const std::ptrdiff_t incx,
+ const float beta, float* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSPMV( &blas_option< UpLo >::value, &n, &alpha, ap, x, &incx, &beta,
+ y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spmv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* ap, const double* x, const std::ptrdiff_t incx,
+ const double beta, double* y, const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSPMV( &blas_option< UpLo >::value, &n, &alpha, ap, x, &incx, &beta,
+ y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to spmv.
+//
+template< typename Value >
 struct spmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixAP, typename VectorX, typename VectorY >
     static return_type invoke( const real_type alpha, const MatrixAP& ap,
             const VectorX& x, const real_type beta, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::spmv( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::matrix_storage(ap), traits::vector_storage(x),
- traits::vector_stride(x), beta, traits::vector_storage(y),
- traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::spmv( order(), uplo(), size_column(ap), alpha,
+ begin_value(ap), begin_value(x), stride(x), beta,
+ begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call spmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the spmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for spmv. Its overload differs for
+// * VectorY&
+//
+template< typename MatrixAP, typename VectorX, typename VectorY >
+inline typename spmv_impl< typename value<
+ MatrixAP >::type >::return_type
+spmv( const typename remove_imaginary< typename value<
+ MatrixAP >::type >::type alpha, const MatrixAP& ap, const VectorX& x,
+ const typename remove_imaginary< typename value<
+ MatrixAP >::type >::type beta, VectorY& y ) {
+ spmv_impl< typename value< MatrixAP >::type >::invoke( alpha, ap, x,
+ beta, y );
+}
+
+//
+// Overloaded function for spmv. Its overload differs for
+// * const VectorY&
+//
 template< typename MatrixAP, typename VectorX, typename VectorY >
-inline typename spmv_impl< typename traits::matrix_traits<
- MatrixAP >::value_type >::return_type
-spmv( const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixAP >::value_type >::real_type alpha, const MatrixAP& ap,
- const VectorX& x, const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixAP >::value_type >::real_type beta, VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixAP >::value_type value_type;
- spmv_impl< value_type >::invoke( alpha, ap, x, beta, y );
+inline typename spmv_impl< typename value<
+ MatrixAP >::type >::return_type
+spmv( const typename remove_imaginary< typename value<
+ MatrixAP >::type >::type alpha, const MatrixAP& ap, const VectorX& x,
+ const typename remove_imaginary< typename value<
+ MatrixAP >::type >::type beta, const VectorY& y ) {
+ spmv_impl< typename value< MatrixAP >::type >::invoke( alpha, ap, x,
+ beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,90 +14,185 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPR_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPR_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void spr( const char uplo, const integer_t n, const float alpha,
- const float* x, const integer_t incx, float* ap ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sspr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* ap ) {
+ cblas_sspr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, ap );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSspr( uplo, n, alpha, x, incx, ap );
-#else
- BLAS_SSPR( &uplo, &n, &alpha, x, &incx, ap );
-#endif
 }
 
-inline void spr( const char uplo, const integer_t n, const double alpha,
- const double* x, const integer_t incx, double* ap ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dspr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* ap ) {
+ cblas_dspr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, ap );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSspr( blas_option< UpLo >::value, n, alpha, x, incx, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSPR( &uplo, &n, &alpha, x, &incx, ap );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSPR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, ap );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSPR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, ap );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to spr.
+//
+template< typename Value >
 struct spr_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename MatrixAP >
     static return_type invoke( const real_type alpha, const VectorX& x,
             MatrixAP& ap ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixAP >::value_type >::value) );
- detail::spr( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::matrix_storage(ap) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixAP >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixAP >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::spr( order(), uplo(), size_column(ap), alpha,
+ begin_value(x), stride(x), begin_value(ap) );
     }
 };
 
-// generic template function to call spr
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the spr_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for spr. Its overload differs for
+// * MatrixAP&
+//
+template< typename VectorX, typename MatrixAP >
+inline typename spr_impl< typename value< VectorX >::type >::return_type
+spr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, MatrixAP& ap ) {
+ spr_impl< typename value< VectorX >::type >::invoke( alpha, x, ap );
+}
+
+//
+// Overloaded function for spr. Its overload differs for
+// * const MatrixAP&
+//
 template< typename VectorX, typename MatrixAP >
-inline typename spr_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-spr( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- MatrixAP& ap ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- spr_impl< value_type >::invoke( alpha, x, ap );
+inline typename spr_impl< typename value< VectorX >::type >::return_type
+spr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const MatrixAP& ap ) {
+ spr_impl< typename value< VectorX >::type >::invoke( alpha, x, ap );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr2.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr2.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/spr2.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,96 +14,201 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPR2_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SPR2_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void spr2( const char uplo, const integer_t n, const float alpha,
- const float* x, const integer_t incx, const float* y,
- const integer_t incy, float* ap ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sspr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* ap ) {
+ cblas_sspr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, y, incy, ap );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSspr2( uplo, n, alpha, x, incx, y, incy, ap );
-#else
- BLAS_SSPR2( &uplo, &n, &alpha, x, &incx, y, &incy, ap );
-#endif
 }
 
-inline void spr2( const char uplo, const integer_t n, const double alpha,
- const double* x, const integer_t incx, const double* y,
- const integer_t incy, double* ap ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dspr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* ap ) {
+ cblas_dspr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, y, incy, ap );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSspr2( blas_option< UpLo >::value, n, alpha, x, incx, y, incy, ap );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSPR2( &uplo, &n, &alpha, x, &incx, y, &incy, ap );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSPR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ ap );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void spr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* ap ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSPR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ ap );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to spr2.
+//
+template< typename Value >
 struct spr2_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixAP >
     static return_type invoke( const real_type alpha, const VectorX& x,
             const VectorY& y, MatrixAP& ap ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixAP >::value_type >::value) );
- detail::spr2( traits::matrix_uplo_tag(ap),
- traits::matrix_num_columns(ap), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(ap) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixAP >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixAP >::value ) );
+ typedef typename result_of::data_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ detail::spr2( order(), uplo(), size_column(ap), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(ap) );
     }
 };
 
-// generic template function to call spr2
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the spr2_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for spr2. Its overload differs for
+// * MatrixAP&
+//
+template< typename VectorX, typename VectorY, typename MatrixAP >
+inline typename spr2_impl< typename value< VectorX >::type >::return_type
+spr2( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ MatrixAP& ap ) {
+ spr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ ap );
+}
+
+//
+// Overloaded function for spr2. Its overload differs for
+// * const MatrixAP&
+//
 template< typename VectorX, typename VectorY, typename MatrixAP >
-inline typename spr2_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-spr2( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- const VectorY& y, MatrixAP& ap ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- spr2_impl< value_type >::invoke( alpha, x, y, ap );
+inline typename spr2_impl< typename value< VectorX >::type >::return_type
+spr2( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ const MatrixAP& ap ) {
+ spr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ ap );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/symv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/symv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/symv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,100 +14,210 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void symv( const char uplo, const integer_t n, const float alpha,
- const float* a, const integer_t lda, const float* x,
- const integer_t incx, const float beta, float* y,
- const integer_t incy ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssymv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* x,
+ const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ cblas_ssymv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, a, lda, x, incx, beta, y, incy );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsymv( uplo, n, alpha, a, lda, x, incx, beta, y, incy );
-#else
- BLAS_SSYMV( &uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
 }
 
-inline void symv( const char uplo, const integer_t n, const double alpha,
- const double* a, const integer_t lda, const double* x,
- const integer_t incx, const double beta, double* y,
- const integer_t incy ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsymv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* x,
+ const std::ptrdiff_t incx, const double beta, double* y,
+ const std::ptrdiff_t incy ) {
+ cblas_dsymv( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, a, lda, x, incx, beta, y, incy );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* x,
+ const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsymv( blas_option< UpLo >::value, n, alpha, a, lda, x, incx, beta,
+ y, incy );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* x,
+ const std::ptrdiff_t incx, const double beta, double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSYMV( &uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* x,
+ const std::ptrdiff_t incx, const float beta, float* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYMV( &blas_option< UpLo >::value, &n, &alpha, a, &lda, x, &incx,
+ &beta, y, &incy );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symv( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* x,
+ const std::ptrdiff_t incx, const double beta, double* y,
+ const std::ptrdiff_t incy ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYMV( &blas_option< UpLo >::value, &n, &alpha, a, &lda, x, &incx,
+ &beta, y, &incy );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to symv.
+//
+template< typename Value >
 struct symv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX, typename VectorY >
     static return_type invoke( const real_type alpha, const MatrixA& a,
             const VectorX& x, const real_type beta, VectorY& y ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- detail::symv( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::matrix_storage(a), traits::leading_dimension(a),
- traits::vector_storage(x), traits::vector_stride(x), beta,
- traits::vector_storage(y), traits::vector_stride(y) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorY >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::symv( order(), uplo(), size_column(a), alpha,
+ begin_value(a), stride_major(a), begin_value(x), stride(x),
+ beta, begin_value(y), stride(y) );
     }
 };
 
-// generic template function to call symv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the symv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for symv. Its overload differs for
+// * VectorY&
+//
+template< typename MatrixA, typename VectorX, typename VectorY >
+inline typename symv_impl< typename value< MatrixA >::type >::return_type
+symv( const typename remove_imaginary< typename value<
+ MatrixA >::type >::type alpha, const MatrixA& a, const VectorX& x,
+ const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, VectorY& y ) {
+ symv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
+}
+
+//
+// Overloaded function for symv. Its overload differs for
+// * const VectorY&
+//
 template< typename MatrixA, typename VectorX, typename VectorY >
-inline typename symv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-symv( const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixA >::value_type >::real_type alpha, const MatrixA& a,
- const VectorX& x, const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixA >::value_type >::real_type beta, VectorY& y ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- symv_impl< value_type >::invoke( alpha, a, x, beta, y );
+inline typename symv_impl< typename value< MatrixA >::type >::return_type
+symv( const typename remove_imaginary< typename value<
+ MatrixA >::type >::type alpha, const MatrixA& a, const VectorX& x,
+ const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, const VectorY& y ) {
+ symv_impl< typename value< MatrixA >::type >::invoke( alpha, a, x,
+ beta, y );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,91 +14,191 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYR_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYR_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void syr( const char uplo, const integer_t n, const float alpha,
- const float* x, const integer_t incx, float* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssyr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* a,
+ const std::ptrdiff_t lda ) {
+ cblas_ssyr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, a, lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsyr( uplo, n, alpha, x, incx, a, lda );
-#else
- BLAS_SSYR( &uplo, &n, &alpha, x, &incx, a, &lda );
-#endif
 }
 
-inline void syr( const char uplo, const integer_t n, const double alpha,
- const double* x, const integer_t incx, double* a,
- const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsyr( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* a,
+ const std::ptrdiff_t lda ) {
+ cblas_dsyr( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, a, lda );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDsyr( uplo, n, alpha, x, incx, a, lda );
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsyr( blas_option< UpLo >::value, n, alpha, x, incx, a, lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDsyr( blas_option< UpLo >::value, n, alpha, x, incx, a, lda );
+}
+
 #else
- BLAS_DSYR( &uplo, &n, &alpha, x, &incx, a, &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, float* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, double* a,
+ const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYR( &blas_option< UpLo >::value, &n, &alpha, x, &incx, a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to syr.
+//
+template< typename Value >
 struct syr_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename MatrixA >
     static return_type invoke( const real_type alpha, const VectorX& x,
             MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::syr( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::syr( order(), uplo(), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call syr
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the syr_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for syr. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename MatrixA >
+inline typename syr_impl< typename value< VectorX >::type >::return_type
+syr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, MatrixA& a ) {
+ syr_impl< typename value< VectorX >::type >::invoke( alpha, x, a );
+}
+
+//
+// Overloaded function for syr. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename MatrixA >
-inline typename syr_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-syr( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- syr_impl< value_type >::invoke( alpha, x, a );
+inline typename syr_impl< typename value< VectorX >::type >::return_type
+syr( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const MatrixA& a ) {
+ syr_impl< typename value< VectorX >::type >::invoke( alpha, x, a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr2.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr2.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/syr2.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,96 +14,202 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYR2_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_SYR2_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void syr2( const char uplo, const integer_t n, const float alpha,
- const float* x, const integer_t incx, const float* y,
- const integer_t incy, float* a, const integer_t lda ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssyr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* a, const std::ptrdiff_t lda ) {
+ cblas_ssyr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, y, incy, a, lda );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsyr2( uplo, n, alpha, x, incx, y, incy, a, lda );
-#else
- BLAS_SSYR2( &uplo, &n, &alpha, x, &incx, y, &incy, a, &lda );
-#endif
 }
 
-inline void syr2( const char uplo, const integer_t n, const double alpha,
- const double* x, const integer_t incx, const double* y,
- const integer_t incy, double* a, const integer_t lda ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsyr2( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ), n,
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* a, const std::ptrdiff_t lda ) {
+ cblas_dsyr2( cblas_option< Order >::value, cblas_option< UpLo >::value, n,
             alpha, x, incx, y, incy, a, lda );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsyr2( blas_option< UpLo >::value, n, alpha, x, incx, y, incy, a,
+ lda );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_DSYR2( &uplo, &n, &alpha, x, &incx, y, &incy, a, &lda );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const float alpha,
+ const float* x, const std::ptrdiff_t incx, const float* y,
+ const std::ptrdiff_t incy, float* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ a, &lda );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void syr2( Order, UpLo, const std::ptrdiff_t n, const double alpha,
+ const double* x, const std::ptrdiff_t incx, const double* y,
+ const std::ptrdiff_t incy, double* a, const std::ptrdiff_t lda ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYR2( &blas_option< UpLo >::value, &n, &alpha, x, &incx, y, &incy,
+ a, &lda );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to syr2.
+//
+template< typename Value >
 struct syr2_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename VectorX, typename VectorY, typename MatrixA >
     static return_type invoke( const real_type alpha, const VectorX& x,
             const VectorY& y, MatrixA& a ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::vector_traits<
- VectorY >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
- VectorX >::value_type, typename traits::matrix_traits<
- MatrixA >::value_type >::value) );
- detail::syr2( traits::matrix_uplo_tag(a),
- traits::matrix_num_columns(a), alpha,
- traits::vector_storage(x), traits::vector_stride(x),
- traits::vector_storage(y), traits::vector_stride(y),
- traits::matrix_storage(a), traits::leading_dimension(a) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< VectorY >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ VectorX >::type >::type, typename remove_const<
+ typename value< MatrixA >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixA >::value ) );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::syr2( order(), uplo(), size_column(a), alpha,
+ begin_value(x), stride(x), begin_value(y), stride(y),
+ begin_value(a), stride_major(a) );
     }
 };
 
-// generic template function to call syr2
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the syr2_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for syr2. Its overload differs for
+// * MatrixA&
+//
+template< typename VectorX, typename VectorY, typename MatrixA >
+inline typename syr2_impl< typename value< VectorX >::type >::return_type
+syr2( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ MatrixA& a ) {
+ syr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
+}
+
+//
+// Overloaded function for syr2. Its overload differs for
+// * const MatrixA&
+//
 template< typename VectorX, typename VectorY, typename MatrixA >
-inline typename syr2_impl< typename traits::vector_traits<
- VectorX >::value_type >::return_type
-syr2( const typename traits::type_traits<
- typename traits::vector_traits<
- VectorX >::value_type >::real_type alpha, const VectorX& x,
- const VectorY& y, MatrixA& a ) {
- typedef typename traits::vector_traits< VectorX >::value_type value_type;
- syr2_impl< value_type >::invoke( alpha, x, y, a );
+inline typename syr2_impl< typename value< VectorX >::type >::return_type
+syr2( const typename remove_imaginary< typename value<
+ VectorX >::type >::type alpha, const VectorX& x, const VectorY& y,
+ const MatrixA& a ) {
+ syr2_impl< typename value< VectorX >::type >::invoke( alpha, x, y,
+ a );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,127 +14,288 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TBMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TBMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void tbmv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const float* a,
- const integer_t lda, float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_stbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k, a, lda, x,
- incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStbmv( uplo, trans, diag, n, k, a, lda, x, incx );
-#else
- BLAS_STBMV( &uplo, &trans, &diag, &n, &k, a, &lda, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ cblas_stbmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ cblas_dtbmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ctbmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ztbmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
 }
 
-inline void tbmv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const double* a,
- const integer_t lda, double* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k, a, lda, x,
- incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStbmv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, k, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DTBMV( &uplo, &trans, &diag, &n, &k, a, &lda, x, &incx );
-#endif
 }
 
-inline void tbmv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const traits::complex_f* a,
- const integer_t lda, traits::complex_f* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtbmv( uplo, trans, diag, n, k, traits::void_ptr(a), lda,
- traits::void_ptr(x), incx );
-#else
- BLAS_CTBMV( &uplo, &trans, &diag, &n, &k, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtbmv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, k, a, lda, x, incx );
 }
 
-inline void tbmv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const traits::complex_d* a,
- const integer_t lda, traits::complex_d* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztbmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTBMV( &uplo, &trans, &diag, &n, &k, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STBMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTBMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTBMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTBMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to tbmv.
+//
+template< typename Value >
 struct tbmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const integer_t k, const MatrixA& a, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::tbmv( traits::matrix_uplo_tag(a), trans, diag,
- traits::matrix_num_columns(a), k, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::vector_storage(x),
- traits::vector_stride(x) );
+ static return_type invoke( const std::ptrdiff_t k, const MatrixA& a,
+ VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::tbmv( order(), uplo(), trans(), diag(),
+ size_column_op(a, trans()), k, begin_value(a),
+ stride_major(a), begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call tbmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the tbmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for tbmv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixA, typename VectorX >
+inline typename tbmv_impl< typename value< MatrixA >::type >::return_type
+tbmv( const std::ptrdiff_t k, const MatrixA& a, VectorX& x ) {
+ tbmv_impl< typename value< MatrixA >::type >::invoke( k, a, x );
+}
+
+//
+// Overloaded function for tbmv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixA, typename VectorX >
-inline typename tbmv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-tbmv( const char trans, const char diag, const integer_t k,
- const MatrixA& a, VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- tbmv_impl< value_type >::invoke( trans, diag, k, a, x );
+inline typename tbmv_impl< typename value< MatrixA >::type >::return_type
+tbmv( const std::ptrdiff_t k, const MatrixA& a, const VectorX& x ) {
+ tbmv_impl< typename value< MatrixA >::type >::invoke( k, a, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbsv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbsv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tbsv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,127 +14,288 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TBSV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TBSV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void tbsv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const float* a,
- const integer_t lda, float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_stbsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k, a, lda, x,
- incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStbsv( uplo, trans, diag, n, k, a, lda, x, incx );
-#else
- BLAS_STBSV( &uplo, &trans, &diag, &n, &k, a, &lda, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ cblas_stbsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ cblas_dtbsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ctbsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ztbsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, k,
+ a, lda, x, incx );
 }
 
-inline void tbsv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const double* a,
- const integer_t lda, double* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtbsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k, a, lda, x,
- incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStbsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, k, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DTBSV( &uplo, &trans, &diag, &n, &k, a, &lda, x, &incx );
-#endif
 }
 
-inline void tbsv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const traits::complex_f* a,
- const integer_t lda, traits::complex_f* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctbsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtbsv( uplo, trans, diag, n, k, traits::void_ptr(a), lda,
- traits::void_ptr(x), incx );
-#else
- BLAS_CTBSV( &uplo, &trans, &diag, &n, &k, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtbsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, k, a, lda, x, incx );
 }
 
-inline void tbsv( const char uplo, const char trans, const char diag,
- const integer_t n, const integer_t k, const traits::complex_d* a,
- const integer_t lda, traits::complex_d* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztbsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, k,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTBSV( &uplo, &trans, &diag, &n, &k, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float* a, const std::ptrdiff_t lda,
+ float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STBSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double* a, const std::ptrdiff_t lda,
+ double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTBSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTBSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tbsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTBSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, &k, a, &lda, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to tbsv.
+//
+template< typename Value >
 struct tbsv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const integer_t k, const MatrixA& a, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::tbsv( traits::matrix_uplo_tag(a), trans, diag,
- traits::matrix_num_columns(a), k, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::vector_storage(x),
- traits::vector_stride(x) );
+ static return_type invoke( const std::ptrdiff_t k, const MatrixA& a,
+ VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::tbsv( order(), uplo(), trans(), diag(),
+ size_column_op(a, trans()), k, begin_value(a),
+ stride_major(a), begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call tbsv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the tbsv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for tbsv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixA, typename VectorX >
+inline typename tbsv_impl< typename value< MatrixA >::type >::return_type
+tbsv( const std::ptrdiff_t k, const MatrixA& a, VectorX& x ) {
+ tbsv_impl< typename value< MatrixA >::type >::invoke( k, a, x );
+}
+
+//
+// Overloaded function for tbsv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixA, typename VectorX >
-inline typename tbsv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-tbsv( const char trans, const char diag, const integer_t k,
- const MatrixA& a, VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- tbsv_impl< value_type >::invoke( trans, diag, k, a, x );
+inline typename tbsv_impl< typename value< MatrixA >::type >::return_type
+tbsv( const std::ptrdiff_t k, const MatrixA& a, const VectorX& x ) {
+ tbsv_impl< typename value< MatrixA >::type >::invoke( k, a, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,123 +14,277 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TPMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TPMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void tpmv( const char uplo, const char trans, const char diag,
- const integer_t n, const float* ap, float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_stpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, ap, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStpmv( uplo, trans, diag, n, ap, x, incx );
-#else
- BLAS_STPMV( &uplo, &trans, &diag, &n, ap, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ cblas_stpmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ cblas_dtpmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ctpmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ztpmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
 }
 
-inline void tpmv( const char uplo, const char trans, const char diag,
- const integer_t n, const double* ap, double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, ap, x, incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStpmv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, ap, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DTPMV( &uplo, &trans, &diag, &n, ap, x, &incx );
-#endif
 }
 
-inline void tpmv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_f* ap, traits::complex_f* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(ap), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtpmv( uplo, trans, diag, n, traits::void_ptr(ap),
- traits::void_ptr(x), incx );
-#else
- BLAS_CTPMV( &uplo, &trans, &diag, &n, traits::complex_ptr(ap),
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtpmv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, ap, x, incx );
 }
 
-inline void tpmv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_d* ap, traits::complex_d* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztpmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(ap), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTPMV( &uplo, &trans, &diag, &n, traits::complex_ptr(ap),
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STPMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTPMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTPMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTPMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to tpmv.
+//
+template< typename Value >
 struct tpmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixAP, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const MatrixAP& ap, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::tpmv( traits::matrix_uplo_tag(ap), trans, diag,
- traits::matrix_num_columns(ap), traits::matrix_storage(ap),
- traits::vector_storage(x), traits::vector_stride(x) );
+ static return_type invoke( const MatrixAP& ap, VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ typedef typename result_of::trans_tag< MatrixAP, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixAP >::type diag;
+ detail::tpmv( order(), uplo(), trans(), diag(),
+ size_column_op(ap, trans()), begin_value(ap), begin_value(x),
+ stride(x) );
     }
 };
 
-// generic template function to call tpmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the tpmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for tpmv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixAP, typename VectorX >
+inline typename tpmv_impl< typename value<
+ MatrixAP >::type >::return_type
+tpmv( const MatrixAP& ap, VectorX& x ) {
+ tpmv_impl< typename value< MatrixAP >::type >::invoke( ap, x );
+}
+
+//
+// Overloaded function for tpmv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixAP, typename VectorX >
-inline typename tpmv_impl< typename traits::matrix_traits<
- MatrixAP >::value_type >::return_type
-tpmv( const char trans, const char diag, const MatrixAP& ap,
- VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixAP >::value_type value_type;
- tpmv_impl< value_type >::invoke( trans, diag, ap, x );
+inline typename tpmv_impl< typename value<
+ MatrixAP >::type >::return_type
+tpmv( const MatrixAP& ap, const VectorX& x ) {
+ tpmv_impl< typename value< MatrixAP >::type >::invoke( ap, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpsv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpsv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/tpsv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,123 +14,277 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TPSV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TPSV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void tpsv( const char uplo, const char trans, const char diag,
- const integer_t n, const float* ap, float* x, const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_stpsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, ap, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStpsv( uplo, trans, diag, n, ap, x, incx );
-#else
- BLAS_STPSV( &uplo, &trans, &diag, &n, ap, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ cblas_stpsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ cblas_dtpsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ctpsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ cblas_ztpsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, ap,
+ x, incx );
 }
 
-inline void tpsv( const char uplo, const char trans, const char diag,
- const integer_t n, const double* ap, double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtpsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, ap, x, incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStpsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, ap, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DTPSV( &uplo, &trans, &diag, &n, ap, x, &incx );
-#endif
 }
 
-inline void tpsv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_f* ap, traits::complex_f* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctpsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(ap), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtpsv( uplo, trans, diag, n, traits::void_ptr(ap),
- traits::void_ptr(x), incx );
-#else
- BLAS_CTPSV( &uplo, &trans, &diag, &n, traits::complex_ptr(ap),
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtpsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, ap, x, incx );
 }
 
-inline void tpsv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_d* ap, traits::complex_d* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztpsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(ap), traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTPSV( &uplo, &trans, &diag, &n, traits::complex_ptr(ap),
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* ap, float* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STPSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* ap, double* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTPSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* ap, std::complex<float>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTPSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void tpsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* ap, std::complex<double>* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTPSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, ap, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to tpsv.
+//
+template< typename Value >
 struct tpsv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixAP, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const MatrixAP& ap, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixAP >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::tpsv( traits::matrix_uplo_tag(ap), trans, diag,
- traits::matrix_num_columns(ap), traits::matrix_storage(ap),
- traits::vector_storage(x), traits::vector_stride(x) );
+ static return_type invoke( const MatrixAP& ap, VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixAP >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixAP >::type order;
+ typedef typename result_of::data_side< MatrixAP >::type uplo;
+ typedef typename result_of::trans_tag< MatrixAP, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixAP >::type diag;
+ detail::tpsv( order(), uplo(), trans(), diag(),
+ size_column_op(ap, trans()), begin_value(ap), begin_value(x),
+ stride(x) );
     }
 };
 
-// generic template function to call tpsv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the tpsv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for tpsv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixAP, typename VectorX >
+inline typename tpsv_impl< typename value<
+ MatrixAP >::type >::return_type
+tpsv( const MatrixAP& ap, VectorX& x ) {
+ tpsv_impl< typename value< MatrixAP >::type >::invoke( ap, x );
+}
+
+//
+// Overloaded function for tpsv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixAP, typename VectorX >
-inline typename tpsv_impl< typename traits::matrix_traits<
- MatrixAP >::value_type >::return_type
-tpsv( const char trans, const char diag, const MatrixAP& ap,
- VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixAP >::value_type value_type;
- tpsv_impl< value_type >::invoke( trans, diag, ap, x );
+inline typename tpsv_impl< typename value<
+ MatrixAP >::type >::return_type
+tpsv( const MatrixAP& ap, const VectorX& x ) {
+ tpsv_impl< typename value< MatrixAP >::type >::invoke( ap, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trmv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trmv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trmv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,123 +14,280 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TRMV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TRMV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void trmv( const char uplo, const char trans, const char diag,
- const integer_t n, const float* a, const integer_t lda, float* x,
- const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_strmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, a, lda, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStrmv( uplo, trans, diag, n, a, lda, x, incx );
-#else
- BLAS_STRMV( &uplo, &trans, &diag, &n, a, &lda, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ cblas_strmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ cblas_dtrmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ cblas_ctrmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ cblas_ztrmv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
 }
 
-inline void trmv( const char uplo, const char trans, const char diag,
- const integer_t n, const double* a, const integer_t lda, double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtrmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, a, lda, x, incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStrmv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_DTRMV( &uplo, &trans, &diag, &n, a, &lda, x, &incx );
-#endif
 }
 
-inline void trmv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_f* a, const integer_t lda,
- traits::complex_f* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctrmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
-#else
- BLAS_CTRMV( &uplo, &trans, &diag, &n, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
 }
 
-inline void trmv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_d* a, const integer_t lda,
- traits::complex_d* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztrmv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTRMV( &uplo, &trans, &diag, &n, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STRMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTRMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTRMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trmv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTRMV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to trmv.
+//
+template< typename Value >
 struct trmv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const MatrixA& a, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::trmv( traits::matrix_uplo_tag(a), trans, diag,
- traits::matrix_num_columns(a), traits::matrix_storage(a),
- traits::leading_dimension(a), traits::vector_storage(x),
- traits::vector_stride(x) );
+ static return_type invoke( const MatrixA& a, VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::trmv( order(), uplo(), trans(), diag(),
+ size_column_op(a, trans()), begin_value(a), stride_major(a),
+ begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call trmv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the trmv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for trmv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixA, typename VectorX >
+inline typename trmv_impl< typename value< MatrixA >::type >::return_type
+trmv( const MatrixA& a, VectorX& x ) {
+ trmv_impl< typename value< MatrixA >::type >::invoke( a, x );
+}
+
+//
+// Overloaded function for trmv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixA, typename VectorX >
-inline typename trmv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-trmv( const char trans, const char diag, const MatrixA& a, VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- trmv_impl< value_type >::invoke( trans, diag, a, x );
+inline typename trmv_impl< typename value< MatrixA >::type >::return_type
+trmv( const MatrixA& a, const VectorX& x ) {
+ trmv_impl< typename value< MatrixA >::type >::invoke( a, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trsv.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trsv.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level2/trsv.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,124 +14,282 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TRSV_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL2_TRSV_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/blas/detail/default_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void trsv( const char uplo, const char trans, const char diag,
- const integer_t n, const float* a, const integer_t lda, float* x,
- const integer_t incx ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_strsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, a, lda, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStrsv( uplo, trans, diag, n, a, lda, x, incx );
-#else
- BLAS_STRSV( &uplo, &trans, &diag, &n, a, &lda, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ cblas_strsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
 }
 
-inline void trsv( const char uplo, const char trans, const char diag,
- const integer_t n, const double* a, const integer_t lda, double* x,
- const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtrsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n, a, lda, x, incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDtrsv( uplo, trans, diag, n, a, lda, x, incx );
-#else
- BLAS_DTRSV( &uplo, &trans, &diag, &n, a, &lda, x, &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ cblas_dtrsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
 }
 
-inline void trsv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_f* a, const integer_t lda,
- traits::complex_f* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctrsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtrsv( uplo, trans, diag, n, traits::void_ptr(a), lda,
- traits::void_ptr(x), incx );
-#else
- BLAS_CTRSV( &uplo, &trans, &diag, &n, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ cblas_ctrsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ cblas_ztrsv( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, cblas_option< Diag >::value, n, a,
+ lda, x, incx );
 }
 
-inline void trsv( const char uplo, const char trans, const char diag,
- const integer_t n, const traits::complex_d* a, const integer_t lda,
- traits::complex_d* x, const integer_t incx ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztrsv( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), n,
- traits::void_ptr(a), lda, traits::void_ptr(x), incx );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStrsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDtrsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtrsv( blas_option< UpLo >::value, blas_option< Trans >::value,
+ blas_option< Diag >::value, n, a, lda, x, incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTRSV( &uplo, &trans, &diag, &n, traits::complex_ptr(a), &lda,
- traits::complex_ptr(x), &incx );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const float* a, const std::ptrdiff_t lda, float* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STRSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const double* a, const std::ptrdiff_t lda, double* x,
+ const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTRSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ std::complex<float>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTRSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans, typename Diag >
+inline void trsv( Order, UpLo, Trans, Diag, const std::ptrdiff_t n,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ std::complex<double>* x, const std::ptrdiff_t incx ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTRSV( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &blas_option< Diag >::value, &n, a, &lda, x, &incx );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to trsv.
+//
+template< typename Value >
 struct trsv_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename VectorX >
- static return_type invoke( const char trans, const char diag,
- const MatrixA& a, VectorX& x ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::vector_traits<
- VectorX >::value_type >::value) );
- detail::trsv( traits::matrix_uplo_tag(a), trans, diag,
- traits::matrix_num_columns(a), traits::matrix_storage(a),
- traits::leading_dimension(a), traits::vector_storage(x),
- traits::vector_stride(x) );
+ static return_type invoke( const MatrixA& a, VectorX& x ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< VectorX >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< VectorX >::value ) );
+ typedef typename detail::default_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::trsv( order(), uplo(), trans(), diag(),
+ size_column_op(a, trans()), begin_value(a), stride_major(a),
+ begin_value(x), stride(x) );
     }
 };
 
-// generic template function to call trsv
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the trsv_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for trsv. Its overload differs for
+// * VectorX&
+//
+template< typename MatrixA, typename VectorX >
+inline typename trsv_impl< typename value< MatrixA >::type >::return_type
+trsv( const MatrixA& a, VectorX& x ) {
+ trsv_impl< typename value< MatrixA >::type >::invoke( a, x );
+}
+
+//
+// Overloaded function for trsv. Its overload differs for
+// * const VectorX&
+//
 template< typename MatrixA, typename VectorX >
-inline typename trsv_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-trsv( const char trans, const char diag, const MatrixA& a, VectorX& x ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- trsv_impl< value_type >::invoke( trans, diag, a, x );
+inline typename trsv_impl< typename value< MatrixA >::type >::return_type
+trsv( const MatrixA& a, const VectorX& x ) {
+ trsv_impl< typename value< MatrixA >::type >::invoke( a, x );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/gemm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/gemm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/gemm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,161 +14,321 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_GEMM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_GEMM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void gemm( const char transa, const char transb, const integer_t m,
- const integer_t n, const integer_t k, const float alpha,
- const float* a, const integer_t lda, const float* b,
- const integer_t ldb, const float beta, float* c,
- const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_sgemm( CblasColMajor,
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( transb == 'N' ? CblasNoTrans : ( transb == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* b,
+ const std::ptrdiff_t ldb, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_sgemm( cblas_option< Order >::value, cblas_option< TransA >::value,
+ cblas_option< TransB >::value, m, n, k, alpha, a, lda, b, ldb,
+ beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* b,
+ const std::ptrdiff_t ldb, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_dgemm( cblas_option< Order >::value, cblas_option< TransA >::value,
+ cblas_option< TransB >::value, m, n, k, alpha, a, lda, b, ldb,
+ beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* b,
+ const std::ptrdiff_t ldb, const std::complex<float> beta,
+ std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ cblas_cgemm( cblas_option< Order >::value, cblas_option< TransA >::value,
+ cblas_option< TransB >::value, m, n, k, &alpha, a, lda, b, ldb,
+ &beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* b,
+ const std::ptrdiff_t ldb, const std::complex<double> beta,
+ std::complex<double>* c, const std::ptrdiff_t ldc ) {
+ cblas_zgemm( cblas_option< Order >::value, cblas_option< TransA >::value,
+ cblas_option< TransB >::value, m, n, k, &alpha, a, lda, b, ldb,
+ &beta, c, ldc );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSgemm( transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c,
- ldc );
-#else
- BLAS_SGEMM( &transa, &transb, &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta,
- c, &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* b,
+ const std::ptrdiff_t ldb, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSgemm( blas_option< TransA >::value, blas_option< TransB >::value,
+ m, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
 }
 
-inline void gemm( const char transa, const char transb, const integer_t m,
- const integer_t n, const integer_t k, const double alpha,
- const double* a, const integer_t lda, const double* b,
- const integer_t ldb, const double beta, double* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dgemm( CblasColMajor,
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( transb == 'N' ? CblasNoTrans : ( transb == 'T' ? CblasTrans : CblasConjTrans ) ),
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* b,
+ const std::ptrdiff_t ldb, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDgemm( blas_option< TransA >::value, blas_option< TransB >::value,
             m, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDgemm( transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c,
- ldc );
-#else
- BLAS_DGEMM( &transa, &transb, &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta,
- c, &ldc );
-#endif
 }
 
-inline void gemm( const char transa, const char transb, const integer_t m,
- const integer_t n, const integer_t k, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* b, const integer_t ldb,
- const traits::complex_f beta, traits::complex_f* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cgemm( CblasColMajor,
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( transb == 'N' ? CblasNoTrans : ( transb == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCgemm( transa, transb, m, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb,
- traits::void_ptr(beta), traits::void_ptr(c), ldc );
-#else
- BLAS_CGEMM( &transa, &transb, &m, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* b,
+ const std::ptrdiff_t ldb, const std::complex<float> beta,
+ std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCgemm( blas_option< TransA >::value, blas_option< TransB >::value,
+ m, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* b,
+ const std::ptrdiff_t ldb, const std::complex<double> beta,
+ std::complex<double>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasZgemm( blas_option< TransA >::value, blas_option< TransB >::value,
+ m, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
 }
 
-inline void gemm( const char transa, const char transb, const integer_t m,
- const integer_t n, const integer_t k, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* b, const integer_t ldb,
- const traits::complex_d beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zgemm( CblasColMajor,
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( transb == 'N' ? CblasNoTrans : ( transb == 'T' ? CblasTrans : CblasConjTrans ) ),
- m, n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasZgemm( transa, transb, m, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb,
- traits::void_ptr(beta), traits::void_ptr(c), ldc );
 #else
- BLAS_ZGEMM( &transa, &transb, &m, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const float alpha,
+ const float* a, const std::ptrdiff_t lda, const float* b,
+ const std::ptrdiff_t ldb, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SGEMM( &blas_option< TransA >::value, &blas_option< TransB >::value,
+ &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k, const double alpha,
+ const double* a, const std::ptrdiff_t lda, const double* b,
+ const std::ptrdiff_t ldb, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DGEMM( &blas_option< TransA >::value, &blas_option< TransB >::value,
+ &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, const std::complex<float>* b,
+ const std::ptrdiff_t ldb, const std::complex<float> beta,
+ std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CGEMM( &blas_option< TransA >::value, &blas_option< TransB >::value,
+ &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename TransA, typename TransB >
+inline void gemm( Order, TransA, TransB, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::ptrdiff_t k,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, const std::complex<double>* b,
+ const std::ptrdiff_t ldb, const std::complex<double> beta,
+ std::complex<double>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZGEMM( &blas_option< TransA >::value, &blas_option< TransB >::value,
+ &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to gemm.
+//
+template< typename Value >
 struct gemm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB, typename MatrixC >
- static return_type invoke( const char transa, const char transb,
- const value_type alpha, const MatrixA& a, const MatrixB& b,
- const value_type beta, MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::gemm( transa, transb, traits::matrix_num_rows(c),
- traits::matrix_num_columns(c),
- (transa=='N' ? traits::matrix_num_columns(a) : traits::matrix_num_rows(a)),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ static return_type invoke( const value_type alpha, const MatrixA& a,
+ const MatrixB& b, const value_type beta, MatrixC& c ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ typedef typename result_of::data_order< MatrixC >::type order;
+ typedef typename result_of::trans_tag< MatrixA, order >::type transa;
+ typedef typename result_of::trans_tag< MatrixB, order >::type transb;
+ detail::gemm( order(), transa(), transb(), size_row(c),
+ size_column(c), size_column(a), alpha, begin_value(a),
+ stride_major(a), begin_value(b), stride_major(b), beta,
+ begin_value(c), stride_major(c) );
     }
 };
 
-// generic template function to call gemm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the gemm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for gemm. Its overload differs for
+// * MatrixC&
+//
 template< typename MatrixA, typename MatrixB, typename MatrixC >
-inline typename gemm_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-gemm( const char transa, const char transb,
- const typename traits::matrix_traits< MatrixA >::value_type alpha,
- const MatrixA& a, const MatrixB& b,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
+inline typename gemm_impl< typename value< MatrixA >::type >::return_type
+gemm( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename value< MatrixA >::type beta,
         MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- gemm_impl< value_type >::invoke( transa, transb, alpha, a, b, beta,
- c );
+ gemm_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
+}
+
+//
+// Overloaded function for gemm. Its overload differs for
+// * const MatrixC&
+//
+template< typename MatrixA, typename MatrixB, typename MatrixC >
+inline typename gemm_impl< typename value< MatrixA >::type >::return_type
+gemm( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename value< MatrixA >::type beta,
+ const MatrixC& c ) {
+ gemm_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/hemm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/hemm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/hemm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,116 +14,225 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HEMM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HEMM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void hemm( const char side, const char uplo, const integer_t m,
- const integer_t n, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* b, const integer_t ldb,
- const traits::complex_f beta, traits::complex_f* c,
- const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_chemm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasChemm( side, uplo, m, n, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb,
- traits::void_ptr(beta), traits::void_ptr(c), ldc );
-#else
- BLAS_CHEMM( &side, &uplo, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_chemm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zhemm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
 }
 
-inline void hemm( const char side, const char uplo, const integer_t m,
- const integer_t n, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* b, const integer_t ldb,
- const traits::complex_d beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zhemm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasChemm( side, blas_option< UpLo >::value, m, n, alpha, a, lda, b,
+ ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHEMM( &side, &uplo, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHEMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void hemm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHEMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to hemm.
+//
+template< typename Value >
 struct hemm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB, typename MatrixC >
     static return_type invoke( const char side, const value_type alpha,
             const MatrixA& a, const MatrixB& b, const value_type beta,
             MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::hemm( side, traits::matrix_uplo_tag(a),
- traits::matrix_num_rows(c), traits::matrix_num_columns(c),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ BOOST_ASSERT( side == 'L' || side == 'R' );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::hemm( order(), side, uplo(), size_row(c),
+ size_column(c), alpha, begin_value(a), stride_major(a),
+ begin_value(b), stride_major(b), beta, begin_value(c),
+ stride_major(c) );
     }
 };
 
-// generic template function to call hemm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the hemm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for hemm. Its overload differs for
+// * MatrixC&
+//
+template< typename MatrixA, typename MatrixB, typename MatrixC >
+inline typename hemm_impl< typename value< MatrixA >::type >::return_type
+hemm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b, const typename value<
+ MatrixA >::type beta, MatrixC& c ) {
+ hemm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b, beta, c );
+}
+
+//
+// Overloaded function for hemm. Its overload differs for
+// * const MatrixC&
+//
 template< typename MatrixA, typename MatrixB, typename MatrixC >
-inline typename hemm_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-hemm( const char side, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const MatrixB& b,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
- MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- hemm_impl< value_type >::invoke( side, alpha, a, b, beta, c );
+inline typename hemm_impl< typename value< MatrixA >::type >::return_type
+hemm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b, const typename value<
+ MatrixA >::type beta, const MatrixC& c ) {
+ hemm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b, beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/her2k.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/her2k.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/her2k.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,113 +14,222 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HER2K_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HER2K_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void her2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* b, const integer_t ldb, const float beta,
- traits::complex_f* c, const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cher2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, beta, traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCher2k( uplo, trans, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb, beta,
- traits::void_ptr(c), ldc );
-#else
- BLAS_CHER2K( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb, &beta,
- traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ cblas_cher2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, b, ldb, beta,
+ c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zher2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, b, ldb, beta,
+ c, ldc );
 }
 
-inline void her2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* b, const integer_t ldb, const double beta,
- traits::complex_d* c, const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zher2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, beta, traits::void_ptr(c), ldc );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCher2k( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, b, ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHER2K( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb, &beta,
- traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHER2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void her2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHER2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to her2k.
+//
+template< typename Value >
 struct her2k_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB, typename MatrixC >
- static return_type invoke( const char trans, const value_type alpha,
- const MatrixA& a, const MatrixB& b, const real_type beta,
- MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::her2k( traits::matrix_uplo_tag(c), trans,
- traits::matrix_num_columns(c),
- (trans=='N' ? traits::matrix_num_columns(a) : traits::matrix_num_rows(a)),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ static return_type invoke( const value_type alpha, const MatrixA& a,
+ const MatrixB& b, const real_type beta, MatrixC& c ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ typedef typename result_of::data_order< MatrixB >::type order;
+ typedef typename result_of::data_side< MatrixC >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::her2k( order(), uplo(), trans(), size_column(c),
+ size_column(a), alpha, begin_value(a), stride_major(a),
+ begin_value(b), stride_major(b), beta, begin_value(c),
+ stride_major(c) );
     }
 };
 
-// generic template function to call her2k
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the her2k_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for her2k. Its overload differs for
+// * MatrixC&
+//
+template< typename MatrixA, typename MatrixB, typename MatrixC >
+inline typename her2k_impl< typename value< MatrixA >::type >::return_type
+her2k( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, MatrixC& c ) {
+ her2k_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
+}
+
+//
+// Overloaded function for her2k. Its overload differs for
+// * const MatrixC&
+//
 template< typename MatrixA, typename MatrixB, typename MatrixC >
-inline typename her2k_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-her2k( const char trans, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const MatrixB& b,
- const typename traits::type_traits< typename traits::matrix_traits<
- MatrixA >::value_type >::real_type beta, MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- her2k_impl< value_type >::invoke( trans, alpha, a, b, beta, c );
+inline typename her2k_impl< typename value< MatrixA >::type >::return_type
+her2k( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, const MatrixC& c ) {
+ her2k_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/herk.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/herk.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/herk.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,104 +14,212 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HERK_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_HERK_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void herk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const float alpha, const traits::complex_f* a,
- const integer_t lda, const float beta, traits::complex_f* c,
- const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_cherk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, traits::void_ptr(a), lda, beta, traits::void_ptr(c),
- ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCherk( uplo, trans, n, k, alpha, traits::void_ptr(a), lda, beta,
- traits::void_ptr(c), ldc );
-#else
- BLAS_CHERK( &uplo, &trans, &n, &k, &alpha, traits::complex_ptr(a), &lda,
- &beta, traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ cblas_cherk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zherk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, beta, c, ldc );
 }
 
-inline void herk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const double alpha, const traits::complex_d* a,
- const integer_t lda, const double beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zherk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, traits::void_ptr(a), lda, beta, traits::void_ptr(c),
- ldc );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCherk( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZHERK( &uplo, &trans, &n, &k, &alpha, traits::complex_ptr(a), &lda,
- &beta, traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const float beta, std::complex<float>* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CHERK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void herk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const double beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZHERK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to herk.
+//
+template< typename Value >
 struct herk_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixC >
- static return_type invoke( const char trans, const real_type alpha,
- const MatrixA& a, const real_type beta, MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::herk( traits::matrix_uplo_tag(c), trans,
- traits::matrix_num_columns(c),
- (trans=='N' ? traits::matrix_num_columns(a) : traits::matrix_num_rows(a)),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ static return_type invoke( const real_type alpha, const MatrixA& a,
+ const real_type beta, MatrixC& c ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ typedef typename result_of::data_order< MatrixC >::type order;
+ typedef typename result_of::data_side< MatrixC >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::herk( order(), uplo(), trans(), size_column(c),
+ size_column(a), alpha, begin_value(a), stride_major(a), beta,
+ begin_value(c), stride_major(c) );
     }
 };
 
-// generic template function to call herk
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the herk_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for herk. Its overload differs for
+// * MatrixC&
+//
+template< typename MatrixA, typename MatrixC >
+inline typename herk_impl< typename value< MatrixA >::type >::return_type
+herk( const typename remove_imaginary< typename value<
+ MatrixA >::type >::type alpha, const MatrixA& a,
+ const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, MatrixC& c ) {
+ herk_impl< typename value< MatrixA >::type >::invoke( alpha, a,
+ beta, c );
+}
+
+//
+// Overloaded function for herk. Its overload differs for
+// * const MatrixC&
+//
 template< typename MatrixA, typename MatrixC >
-inline typename herk_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-herk( const char trans, const typename traits::type_traits<
- typename traits::matrix_traits<
- MatrixA >::value_type >::real_type alpha, const MatrixA& a,
- const typename traits::type_traits< typename traits::matrix_traits<
- MatrixA >::value_type >::real_type beta, MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- herk_impl< value_type >::invoke( trans, alpha, a, beta, c );
+inline typename herk_impl< typename value< MatrixA >::type >::return_type
+herk( const typename remove_imaginary< typename value<
+ MatrixA >::type >::type alpha, const MatrixA& a,
+ const typename remove_imaginary< typename value<
+ MatrixA >::type >::type beta, const MatrixC& c ) {
+ herk_impl< typename value< MatrixA >::type >::invoke( alpha, a,
+ beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/symm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/symm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/symm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,148 +14,315 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYMM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYMM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void symm( const char side, const char uplo, const integer_t m,
- const integer_t n, const float alpha, const float* a,
- const integer_t lda, const float* b, const integer_t ldb,
- const float beta, float* c, const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssymm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n, alpha, a, lda, b,
- ldb, beta, c, ldc );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ cblas_ssymm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, alpha, a, lda, b, ldb, beta, c,
+ ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ cblas_dsymm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, alpha, a, lda, b, ldb, beta, c,
+ ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_csymm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zsymm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, m, n, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsymm( side, uplo, m, n, alpha, a, lda, b, ldb, beta, c, ldc );
-#else
- BLAS_SSYMM( &side, &uplo, &m, &n, &alpha, a, &lda, b, &ldb, &beta, c,
- &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsymm( side, blas_option< UpLo >::value, m, n, alpha, a, lda, b,
+ ldb, beta, c, ldc );
 }
 
-inline void symm( const char side, const char uplo, const integer_t m,
- const integer_t n, const double alpha, const double* a,
- const integer_t lda, const double* b, const integer_t ldb,
- const double beta, double* c, const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsymm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n, alpha, a, lda, b,
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDsymm( side, blas_option< UpLo >::value, m, n, alpha, a, lda, b,
             ldb, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDsymm( side, uplo, m, n, alpha, a, lda, b, ldb, beta, c, ldc );
-#else
- BLAS_DSYMM( &side, &uplo, &m, &n, &alpha, a, &lda, b, &ldb, &beta, c,
- &ldc );
-#endif
 }
 
-inline void symm( const char side, const char uplo, const integer_t m,
- const integer_t n, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* b, const integer_t ldb,
- const traits::complex_f beta, traits::complex_f* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_csymm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCsymm( side, uplo, m, n, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb,
- traits::void_ptr(beta), traits::void_ptr(c), ldc );
-#else
- BLAS_CSYMM( &side, &uplo, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCsymm( side, blas_option< UpLo >::value, m, n, alpha, a, lda, b,
+ ldb, beta, c, ldc );
 }
 
-inline void symm( const char side, const char uplo, const integer_t m,
- const integer_t n, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* b, const integer_t ldb,
- const traits::complex_d beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zsymm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZSYMM( &side, &uplo, &m, &n, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CSYMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo >
+inline void symm( Order, const char side, UpLo, const std::ptrdiff_t m,
+ const std::ptrdiff_t n, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZSYMM( &side, &blas_option< UpLo >::value, &m, &n, &alpha, a, &lda,
+ b, &ldb, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to symm.
+//
+template< typename Value >
 struct symm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB, typename MatrixC >
     static return_type invoke( const char side, const value_type alpha,
             const MatrixA& a, const MatrixB& b, const value_type beta,
             MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::symm( side, traits::matrix_uplo_tag(a),
- traits::matrix_num_rows(c), traits::matrix_num_columns(c),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ BOOST_ASSERT( side == 'L' || side == 'R' );
+ typedef typename result_of::data_order< MatrixA >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ detail::symm( order(), side, uplo(), size_row(c),
+ size_column(c), alpha, begin_value(a), stride_major(a),
+ begin_value(b), stride_major(b), beta, begin_value(c),
+ stride_major(c) );
     }
 };
 
-// generic template function to call symm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the symm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for symm. Its overload differs for
+// * MatrixC&
+//
+template< typename MatrixA, typename MatrixB, typename MatrixC >
+inline typename symm_impl< typename value< MatrixA >::type >::return_type
+symm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b, const typename value<
+ MatrixA >::type beta, MatrixC& c ) {
+ symm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b, beta, c );
+}
+
+//
+// Overloaded function for symm. Its overload differs for
+// * const MatrixC&
+//
 template< typename MatrixA, typename MatrixB, typename MatrixC >
-inline typename symm_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-symm( const char side, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const MatrixB& b,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
- MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- symm_impl< value_type >::invoke( side, alpha, a, b, beta, c );
+inline typename symm_impl< typename value< MatrixA >::type >::return_type
+symm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b, const typename value<
+ MatrixA >::type beta, const MatrixC& c ) {
+ symm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b, beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syr2k.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syr2k.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syr2k.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,149 +14,315 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYR2K_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYR2K_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void syr2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const float alpha, const float* a,
- const integer_t lda, const float* b, const integer_t ldb,
- const float beta, float* c, const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssyr2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, a, lda, b, ldb, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsyr2k( uplo, trans, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
-#else
- BLAS_SSYR2K( &uplo, &trans, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c,
- &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ cblas_ssyr2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, b, ldb, beta,
+ c, ldc );
 }
 
-inline void syr2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const double alpha, const double* a,
- const integer_t lda, const double* b, const integer_t ldb,
- const double beta, double* c, const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsyr2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, a, lda, b, ldb, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDsyr2k( uplo, trans, n, k, alpha, a, lda, b, ldb, beta, c, ldc );
-#else
- BLAS_DSYR2K( &uplo, &trans, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c,
- &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ cblas_dsyr2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, b, ldb, beta,
+ c, ldc );
 }
 
-inline void syr2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f* b, const integer_t ldb,
- const traits::complex_f beta, traits::complex_f* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_csyr2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCsyr2k( uplo, trans, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb,
- traits::void_ptr(beta), traits::void_ptr(c), ldc );
-#else
- BLAS_CSYR2K( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_csyr2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zsyr2k( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, b, ldb, &beta,
+ c, ldc );
 }
 
-inline void syr2k( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d* b, const integer_t ldb,
- const traits::complex_d beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zsyr2k( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb, traits::void_ptr(&beta),
- traits::void_ptr(c), ldc );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsyr2k( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, b, ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDsyr2k( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, b, ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCsyr2k( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, b, ldb, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZSYR2K( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(b), &ldb,
- traits::complex_ptr(&beta), traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float* b, const std::ptrdiff_t ldb,
+ const float beta, float* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYR2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double* b, const std::ptrdiff_t ldb,
+ const double beta, double* c, const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYR2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float>* b, const std::ptrdiff_t ldb,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CSYR2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syr2k( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double>* b, const std::ptrdiff_t ldb,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZSYR2K( &blas_option< UpLo >::value, &blas_option< Trans >::value,
+ &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to syr2k.
+//
+template< typename Value >
 struct syr2k_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB, typename MatrixC >
- static return_type invoke( const char trans, const value_type alpha,
- const MatrixA& a, const MatrixB& b, const value_type beta,
- MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::syr2k( traits::matrix_uplo_tag(c), trans,
- traits::matrix_num_columns(c),
- (trans=='N' ? traits::matrix_num_columns(a) : traits::matrix_num_rows(a)),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ static return_type invoke( const value_type alpha, const MatrixA& a,
+ const MatrixB& b, const value_type beta, MatrixC& c ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ typedef typename result_of::data_order< MatrixB >::type order;
+ typedef typename result_of::data_side< MatrixC >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::syr2k( order(), uplo(), trans(), size_column(c),
+ size_column(a), alpha, begin_value(a), stride_major(a),
+ begin_value(b), stride_major(b), beta, begin_value(c),
+ stride_major(c) );
     }
 };
 
-// generic template function to call syr2k
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the syr2k_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for syr2k. Its overload differs for
+// * MatrixC&
+//
 template< typename MatrixA, typename MatrixB, typename MatrixC >
-inline typename syr2k_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-syr2k( const char trans, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a, const MatrixB& b,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
+inline typename syr2k_impl< typename value< MatrixA >::type >::return_type
+syr2k( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename value< MatrixA >::type beta,
         MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- syr2k_impl< value_type >::invoke( trans, alpha, a, b, beta, c );
+ syr2k_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
+}
+
+//
+// Overloaded function for syr2k. Its overload differs for
+// * const MatrixC&
+//
+template< typename MatrixA, typename MatrixB, typename MatrixC >
+inline typename syr2k_impl< typename value< MatrixA >::type >::return_type
+syr2k( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const MatrixB& b, const typename value< MatrixA >::type beta,
+ const MatrixC& c ) {
+ syr2k_impl< typename value< MatrixA >::type >::invoke( alpha, a, b,
+ beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syrk.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syrk.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/syrk.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,140 +14,302 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYRK_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_SYRK_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void syrk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const float alpha, const float* a,
- const integer_t lda, const float beta, float* c,
- const integer_t ldc ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ssyrk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, a, lda, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasSsyrk( uplo, trans, n, k, alpha, a, lda, beta, c, ldc );
-#else
- BLAS_SSYRK( &uplo, &trans, &n, &k, &alpha, a, &lda, &beta, c, &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_ssyrk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, beta, c, ldc );
 }
 
-inline void syrk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const double alpha, const double* a,
- const integer_t lda, const double beta, double* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dsyrk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, alpha, a, lda, beta, c, ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDsyrk( uplo, trans, n, k, alpha, a, lda, beta, c, ldc );
-#else
- BLAS_DSYRK( &uplo, &trans, &n, &k, &alpha, a, &lda, &beta, c, &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_dsyrk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, alpha, a, lda, beta, c, ldc );
 }
 
-inline void syrk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_f alpha,
- const traits::complex_f* a, const integer_t lda,
- const traits::complex_f beta, traits::complex_f* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_csyrk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(&beta), traits::void_ptr(c), ldc );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCsyrk( uplo, trans, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(beta),
- traits::void_ptr(c), ldc );
-#else
- BLAS_CSYRK( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(&beta),
- traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_csyrk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, &beta, c,
+ ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ cblas_zsyrk( cblas_option< Order >::value, cblas_option< UpLo >::value,
+ cblas_option< Trans >::value, n, k, &alpha, a, lda, &beta, c,
+ ldc );
 }
 
-inline void syrk( const char uplo, const char trans, const integer_t n,
- const integer_t k, const traits::complex_d alpha,
- const traits::complex_d* a, const integer_t lda,
- const traits::complex_d beta, traits::complex_d* c,
- const integer_t ldc ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_zsyrk( CblasColMajor, ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( trans == 'N' ? CblasNoTrans : ( trans == 'T' ? CblasTrans : CblasConjTrans ) ),
- n, k, traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(&beta), traits::void_ptr(c), ldc );
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasZsyrk( uplo, trans, n, k, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(beta),
- traits::void_ptr(c), ldc );
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasSsyrk( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDsyrk( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCsyrk( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, beta, c, ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasZsyrk( blas_option< UpLo >::value, blas_option< Trans >::value, n,
+ k, alpha, a, lda, beta, c, ldc );
+}
+
 #else
- BLAS_ZSYRK( &uplo, &trans, &n, &k, traits::complex_ptr(&alpha),
- traits::complex_ptr(a), &lda, traits::complex_ptr(&beta),
- traits::complex_ptr(c), &ldc );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const float alpha, const float* a,
+ const std::ptrdiff_t lda, const float beta, float* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_SSYRK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const double alpha, const double* a,
+ const std::ptrdiff_t lda, const double beta, double* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DSYRK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<float> alpha,
+ const std::complex<float>* a, const std::ptrdiff_t lda,
+ const std::complex<float> beta, std::complex<float>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CSYRK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename Trans >
+inline void syrk( Order, UpLo, Trans, const std::ptrdiff_t n,
+ const std::ptrdiff_t k, const std::complex<double> alpha,
+ const std::complex<double>* a, const std::ptrdiff_t lda,
+ const std::complex<double> beta, std::complex<double>* c,
+ const std::ptrdiff_t ldc ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZSYRK( &blas_option< UpLo >::value, &blas_option< Trans >::value, &n,
+ &k, &alpha, a, &lda, &beta, c, &ldc );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to syrk.
+//
+template< typename Value >
 struct syrk_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixC >
- static return_type invoke( const char trans, const value_type alpha,
- const MatrixA& a, const value_type beta, MatrixC& c ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixC >::value_type >::value) );
- detail::syrk( traits::matrix_uplo_tag(c), trans,
- traits::matrix_num_columns(c),
- (trans=='N' ? traits::matrix_num_columns(a) : traits::matrix_num_rows(a)),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), beta, traits::matrix_storage(c),
- traits::leading_dimension(c) );
+ static return_type invoke( const value_type alpha, const MatrixA& a,
+ const value_type beta, MatrixC& c ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixC >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixC >::value ) );
+ typedef typename result_of::data_order< MatrixC >::type order;
+ typedef typename result_of::data_side< MatrixC >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type trans;
+ detail::syrk( order(), uplo(), trans(), size_column(c),
+ size_column(a), alpha, begin_value(a), stride_major(a), beta,
+ begin_value(c), stride_major(c) );
     }
 };
 
-// generic template function to call syrk
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the syrk_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for syrk. Its overload differs for
+// * MatrixC&
+//
+template< typename MatrixA, typename MatrixC >
+inline typename syrk_impl< typename value< MatrixA >::type >::return_type
+syrk( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const typename value< MatrixA >::type beta, MatrixC& c ) {
+ syrk_impl< typename value< MatrixA >::type >::invoke( alpha, a,
+ beta, c );
+}
+
+//
+// Overloaded function for syrk. Its overload differs for
+// * const MatrixC&
+//
 template< typename MatrixA, typename MatrixC >
-inline typename syrk_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-syrk( const char trans, const typename traits::matrix_traits<
- MatrixA >::value_type alpha, const MatrixA& a,
- const typename traits::matrix_traits< MatrixA >::value_type beta,
- MatrixC& c ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- syrk_impl< value_type >::invoke( trans, alpha, a, beta, c );
+inline typename syrk_impl< typename value< MatrixA >::type >::return_type
+syrk( const typename value< MatrixA >::type alpha, const MatrixA& a,
+ const typename value< MatrixA >::type beta, const MatrixC& c ) {
+ syrk_impl< typename value< MatrixA >::type >::invoke( alpha, a,
+ beta, c );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trmm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trmm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trmm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,144 +14,313 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_TRMM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_TRMM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void trmm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const float alpha, const float* a, const integer_t lda, float* b,
- const integer_t ldb ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_strmm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n, alpha, a, lda,
- b, ldb );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_strmm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_dtrmm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_ctrmm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, &alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_ztrmm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, &alpha, a, lda, b, ldb );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStrmm( side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb );
-#else
- BLAS_STRMM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a, &lda, b,
- &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStrmm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
+ b, ldb );
 }
 
-inline void trmm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const double alpha, const double* a, const integer_t lda, double* b,
- const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtrmm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n, alpha, a, lda,
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDtrmm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
             b, ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDtrmm( side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb );
-#else
- BLAS_DTRMM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a, &lda, b,
- &ldb );
-#endif
 }
 
-inline void trmm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* a,
- const integer_t lda, traits::complex_f* b, const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctrmm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtrmm( side, uplo, transa, diag, m, n, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb );
-#else
- BLAS_CTRMM( &side, &uplo, &transa, &diag, &m, &n,
- traits::complex_ptr(&alpha), traits::complex_ptr(a), &lda,
- traits::complex_ptr(b), &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtrmm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
+ b, ldb );
 }
 
-inline void trmm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* a,
- const integer_t lda, traits::complex_d* b, const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztrmm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
     // NOT FOUND();
+}
+
 #else
- BLAS_ZTRMM( &side, &uplo, &transa, &diag, &m, &n,
- traits::complex_ptr(&alpha), traits::complex_ptr(a), &lda,
- traits::complex_ptr(b), &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STRMM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTRMM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTRMM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trmm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTRMM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to trmm.
+//
+template< typename Value >
 struct trmm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB >
- static return_type invoke( const char side, const char transa,
- const char diag, const value_type alpha, const MatrixA& a,
- MatrixB& b ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- detail::trmm( side, traits::matrix_uplo_tag(a), transa, diag,
- traits::matrix_num_rows(b), traits::matrix_num_columns(b),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b) );
+ static return_type invoke( const char side, const value_type alpha,
+ const MatrixA& a, MatrixB& b ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixB >::value ) );
+ BOOST_ASSERT( side == 'L' || side == 'R' );
+ typedef typename result_of::data_order< MatrixB >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type transa;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::trmm( order(), side, uplo(), transa(), diag(),
+ size_row(b), size_column(b), alpha, begin_value(a),
+ stride_major(a), begin_value(b), stride_major(b) );
     }
 };
 
-// generic template function to call trmm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the trmm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for trmm. Its overload differs for
+// * MatrixB&
+//
 template< typename MatrixA, typename MatrixB >
-inline typename trmm_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-trmm( const char side, const char transa, const char diag,
- const typename traits::matrix_traits< MatrixA >::value_type alpha,
+inline typename trmm_impl< typename value< MatrixA >::type >::return_type
+trmm( const char side, const typename value< MatrixA >::type alpha,
         const MatrixA& a, MatrixB& b ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- trmm_impl< value_type >::invoke( side, transa, diag, alpha, a, b );
+ trmm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b );
+}
+
+//
+// Overloaded function for trmm. Its overload differs for
+// * const MatrixB&
+//
+template< typename MatrixA, typename MatrixB >
+inline typename trmm_impl< typename value< MatrixA >::type >::return_type
+trmm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b ) {
+ trmm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b );
 }
 
 } // namespace blas

Modified: sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trsm.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trsm.hpp (original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/blas/level3/trsm.hpp 2009-12-23 10:12:29 EST (Wed, 23 Dec 2009)
@@ -14,145 +14,315 @@
 #ifndef BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_TRSM_HPP
 #define BOOST_NUMERIC_BINDINGS_BLAS_LEVEL3_TRSM_HPP
 
-// Include header of configured BLAS interface
+#include <boost/assert.hpp>
+#include <boost/numeric/bindings/data_order.hpp>
+#include <boost/numeric/bindings/data_side.hpp>
+#include <boost/numeric/bindings/diag_tag.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
+#include <boost/numeric/bindings/is_mutable.hpp>
+#include <boost/numeric/bindings/remove_imaginary.hpp>
+#include <boost/numeric/bindings/size.hpp>
+#include <boost/numeric/bindings/stride.hpp>
+#include <boost/numeric/bindings/trans_tag.hpp>
+#include <boost/numeric/bindings/value.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+//
+// The BLAS-backend is selected by defining a pre-processor variable,
+// which can be one of
+// * for CBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
+// * for CUBLAS, define BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
+// * netlib-compatible BLAS is the default
+//
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
 #include <boost/numeric/bindings/blas/detail/cblas.h>
+#include <boost/numeric/bindings/blas/detail/cblas_option.hpp>
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
 #include <boost/numeric/bindings/blas/detail/cublas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #else
 #include <boost/numeric/bindings/blas/detail/blas.h>
+#include <boost/numeric/bindings/blas/detail/blas_option.hpp>
 #endif
 
-#include <boost/mpl/bool.hpp>
-#include <boost/numeric/bindings/traits/traits.hpp>
-#include <boost/numeric/bindings/traits/type_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 namespace boost {
 namespace numeric {
 namespace bindings {
 namespace blas {
 
-// The detail namespace is used for overloads on value type,
-// and to dispatch to the right routine
-
+//
+// The detail namespace contains value-type-overloaded functions that
+// dispatch to the appropriate back-end BLAS-routine.
+//
 namespace detail {
 
-inline void trsm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const float alpha, const float* a, const integer_t lda, float* b,
- const integer_t ldb ) {
 #if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_strsm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n, alpha, a, lda,
- b, ldb );
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_strsm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_dtrsm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_ctrsm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, &alpha, a, lda, b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ cblas_ztrsm( cblas_option< Order >::value, cblas_option< Side >::value,
+ cblas_option< UpLo >::value, cblas_option< TransA >::value,
+ cblas_option< Diag >::value, m, n, &alpha, a, lda, b, ldb );
+}
+
 #elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasStrsm( side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb );
-#else
- BLAS_STRSM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a, &lda, b,
- &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasStrsm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
+ b, ldb );
 }
 
-inline void trsm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const double alpha, const double* a, const integer_t lda, double* b,
- const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_dtrsm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n, alpha, a, lda,
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasDtrsm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
             b, ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasDtrsm( side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb );
-#else
- BLAS_DTRSM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a, &lda, b,
- &ldb );
-#endif
 }
 
-inline void trsm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const traits::complex_f alpha, const traits::complex_f* a,
- const integer_t lda, traits::complex_f* b, const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ctrsm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasCtrsm( side, uplo, transa, diag, m, n, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb );
-#else
- BLAS_CTRSM( &side, &uplo, &transa, &diag, &m, &n,
- traits::complex_ptr(&alpha), traits::complex_ptr(a), &lda,
- traits::complex_ptr(b), &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasCtrsm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
+ b, ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * CUBLAS backend
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ cublasZtrsm( side, blas_option< UpLo >::value, blas_option<
+ TransA >::value, blas_option< Diag >::value, m, n, alpha, a, lda,
+ b, ldb );
 }
 
-inline void trsm( const char side, const char uplo, const char transa,
- const char diag, const integer_t m, const integer_t n,
- const traits::complex_d alpha, const traits::complex_d* a,
- const integer_t lda, traits::complex_d* b, const integer_t ldb ) {
-#if defined BOOST_NUMERIC_BINDINGS_BLAS_CBLAS
- cblas_ztrsm( CblasColMajor, ( uplo == 'L' ? CblasLeft : CblasRight ),
- ( uplo == 'U' ? CblasUpper : CblasLower ),
- ( transa == 'N' ? CblasNoTrans : ( transa == 'T' ? CblasTrans : CblasConjTrans ) ),
- ( uplo == 'N' ? CblasNonUnit : CblasUnit ), m, n,
- traits::void_ptr(&alpha), traits::void_ptr(a), lda,
- traits::void_ptr(b), ldb );
-#elif defined BOOST_NUMERIC_BINDINGS_BLAS_CUBLAS
- cublasZtrsm( side, uplo, transa, diag, m, n, traits::void_ptr(alpha),
- traits::void_ptr(a), lda, traits::void_ptr(b), ldb );
 #else
- BLAS_ZTRSM( &side, &uplo, &transa, &diag, &m, &n,
- traits::complex_ptr(&alpha), traits::complex_ptr(a), &lda,
- traits::complex_ptr(b), &ldb );
-#endif
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * float value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const float alpha,
+ const float* a, const std::ptrdiff_t lda, float* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_STRSM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * double value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n, const double alpha,
+ const double* a, const std::ptrdiff_t lda, double* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_DTRSM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
 }
 
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<float> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<float> alpha, const std::complex<float>* a,
+ const std::ptrdiff_t lda, std::complex<float>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_CTRSM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+//
+// Overloaded function for dispatching to
+// * netlib-compatible BLAS backend (the default)
+// * complex<double> value-type
+//
+template< typename Order, typename UpLo, typename TransA, typename Diag >
+inline void trsm( Order, const char side, UpLo, TransA, Diag,
+ const std::ptrdiff_t m, const std::ptrdiff_t n,
+ const std::complex<double> alpha, const std::complex<double>* a,
+ const std::ptrdiff_t lda, std::complex<double>* b,
+ const std::ptrdiff_t ldb ) {
+ BOOST_STATIC_ASSERT( (is_column_major<Order>::value) );
+ BLAS_ZTRSM( &side, &blas_option< UpLo >::value, &blas_option<
+ TransA >::value, &blas_option< Diag >::value, &m, &n, &alpha, a,
+ &lda, b, &ldb );
+}
+
+#endif
 
 } // namespace detail
 
-// value-type based template
-template< typename ValueType >
+//
+// Value-type based template class. Use this class if you need a type
+// for dispatching to trsm.
+//
+template< typename Value >
 struct trsm_impl {
 
- typedef ValueType value_type;
- typedef typename traits::type_traits<ValueType>::real_type real_type;
+ typedef Value value_type;
+ typedef typename remove_imaginary< Value >::type real_type;
     typedef void return_type;
 
- // static template member function
+ //
+ // Static member function that
+ // * Deduces the required arguments for dispatching to BLAS, and
+ // * Asserts that most arguments make sense.
+ //
     template< typename MatrixA, typename MatrixB >
- static return_type invoke( const char side, const char transa,
- const char diag, const value_type alpha, const MatrixA& a,
- MatrixB& b ) {
- BOOST_STATIC_ASSERT( (boost::is_same< typename traits::matrix_traits<
- MatrixA >::value_type, typename traits::matrix_traits<
- MatrixB >::value_type >::value) );
- detail::trsm( side, traits::matrix_uplo_tag(a), transa, diag,
- traits::matrix_num_rows(b), traits::matrix_num_columns(b),
- alpha, traits::matrix_storage(a),
- traits::leading_dimension(a), traits::matrix_storage(b),
- traits::leading_dimension(b) );
+ static return_type invoke( const char side, const value_type alpha,
+ const MatrixA& a, MatrixB& b ) {
+ BOOST_STATIC_ASSERT( (is_same< typename remove_const< typename value<
+ MatrixA >::type >::type, typename remove_const<
+ typename value< MatrixB >::type >::type >::value) );
+ BOOST_STATIC_ASSERT( (is_mutable< MatrixB >::value ) );
+ BOOST_ASSERT( side == 'L' || side == 'R' );
+ typedef typename result_of::data_order< MatrixB >::type order;
+ typedef typename result_of::data_side< MatrixA >::type uplo;
+ typedef typename result_of::trans_tag< MatrixA, order >::type transa;
+ typedef typename result_of::diag_tag< MatrixA >::type diag;
+ detail::trsm( order(), side, uplo(), transa(), diag(),
+ size_row(b), size_column(b), alpha, begin_value(a),
+ stride_major(a), begin_value(b), stride_major(b) );
     }
 };
 
-// generic template function to call trsm
+//
+// Functions for direct use. These functions are overloaded for temporaries,
+// so that wrapped types can still be passed and used for write-access. Calls
+// to these functions are passed to the trsm_impl classes. In the
+// documentation, the const-overloads are collapsed to avoid a large number of
+// prototypes which are very similar.
+//
+
+//
+// Overloaded function for trsm. Its overload differs for
+// * MatrixB&
+//
 template< typename MatrixA, typename MatrixB >
-inline typename trsm_impl< typename traits::matrix_traits<
- MatrixA >::value_type >::return_type
-trsm( const char side, const char transa, const char diag,
- const typename traits::matrix_traits< MatrixA >::value_type alpha,
+inline typename trsm_impl< typename value< MatrixA >::type >::return_type
+trsm( const char side, const typename value< MatrixA >::type alpha,
         const MatrixA& a, MatrixB& b ) {
- typedef typename traits::matrix_traits< MatrixA >::value_type value_type;
- trsm_impl< value_type >::invoke( side, transa, diag, alpha, a, b );
+ trsm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b );
+}
+
+//
+// Overloaded function for trsm. Its overload differs for
+// * const MatrixB&
+//
+template< typename MatrixA, typename MatrixB >
+inline typename trsm_impl< typename value< MatrixA >::type >::return_type
+trsm( const char side, const typename value< MatrixA >::type alpha,
+ const MatrixA& a, const MatrixB& b ) {
+ trsm_impl< typename value< MatrixA >::type >::invoke( side, alpha,
+ a, b );
 }
 
 } // namespace blas


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk