LCOV - code coverage report
Current view: top level - tools - MatrixSquareBracketsAccess.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 12 12 100.0 %
Date: 2024-10-18 14:00:25 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_MatrixSquareBracketsAccess_h
      23             : #define __PLUMED_tools_MatrixSquareBracketsAccess_h
      24             : 
      25             : namespace PLMD {
      26             : 
      27             : /**
      28             : Utility class to add [][] access
      29             : 
      30             : \tparam T The type of the matrix class.
      31             : \tparam C The type of the returned value.
      32             : \tparam I The type of the first index (default unsigned).
      33             : \tparam J The type of the second index (default unsigned).
      34             : 
      35             : It implements the trick described in C++ FAQ 13.12 to allow [][] access
      36             : to matrix-like classes, based on the (,) syntax, thus translating
      37             : [i][j] into (i,j).  In practice, one only needs to implement the (,) syntax and to inherit from
      38             : MatrixSquareBracketsAccess.
      39             : The first template parameter (T) should be the
      40             : class itself, the second (C) is the type of the returned value,
      41             : and the third (I) and fourth (J) are the types of the two indexes (unsigned by default).
      42             : As everything is inlined, no overhead is expected.
      43             : 
      44             : \verbatim
      45             : 
      46             : class MyMatrixClass:
      47             :   public MatrixSquareBracketsAccess<MyMatrixClass,double>
      48             : {
      49             :   double data[16];
      50             : public:
      51             :   double & operator ()(unsigned i,unsigned j){
      52             :     return data[4*i+j];
      53             :   }
      54             :   const double & operator ()(unsigned i,unsigned j)const{
      55             :     return data[4*i+j];
      56             :   }
      57             : };
      58             : 
      59             : int main(){
      60             :   MyMatrixClass m;
      61             :   m[0][1]=3.0;
      62             :   return 0;
      63             : }
      64             : \endverbatim
      65             : 
      66             : */
      67             : 
      68             : template<class T,class C,class I=unsigned,class J=unsigned>
      69             : class MatrixSquareBracketsAccess {
      70             : /// Small utility class which just contains a pointer to the T and the row number
      71             :   class Const_row {
      72             :     friend class MatrixSquareBracketsAccess; // this so as to allow only T to instantiate Const_row
      73             :     // the user should not manipulate it directly
      74             :     const MatrixSquareBracketsAccess& t;
      75             :     const I i;
      76             :     Const_row(const MatrixSquareBracketsAccess&t,I i); // constructor is private and cannot be manipulated by the user
      77             :   public:
      78             :     /// access element
      79             :     const C & operator[] (J j)const;
      80             :   };
      81             : /// Small utility class which just contains a pointer to the T and the row number
      82             :   class Row {
      83             :     friend class MatrixSquareBracketsAccess; // this so as to allow only T to instantiate Const_row
      84             :     // the user should not manipulate it directly
      85             :     MatrixSquareBracketsAccess& t;
      86             :     const I i;
      87             :     Row(MatrixSquareBracketsAccess&t,I i); // constructor is private and cannot be manipulated by the user
      88             :   public:
      89             :     /// access element
      90             :     C & operator[] (J j);
      91             :   };
      92             : public:
      93             : /// access element (with [][] syntax)
      94             :   Row operator[] (I i);
      95             : /// access element (with [][] syntax)
      96             :   Const_row operator[] (I i)const;
      97             : };
      98             : 
      99             : template<class T,class C,class I,class J>
     100     3523551 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
     101     3523551 :   t(t),i(i) {}
     102             : 
     103             : template<class T,class C,class I,class J>
     104   129092208 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
     105   129092208 :   t(t),i(i) {}
     106             : 
     107             : template<class T,class C,class I,class J>
     108     3523551 : const C & MatrixSquareBracketsAccess<T,C,I,J>::Const_row::operator[] (J j)const {
     109             : // This appears as a reference to a temporary object
     110             : // however, in reality we know it is a reference to an object that is stored in the
     111             : // t object. We thus suppress the warning raised by cppcheck
     112     3523551 :   return (*static_cast<const T*>(&t))(i,j);
     113             : }
     114             : 
     115             : template<class T,class C,class I,class J>
     116   129092208 : C & MatrixSquareBracketsAccess<T,C,I,J>::Row::operator[] (J j) {
     117             : // This appears as a reference to a temporary object
     118             : // however, in reality we know it is a reference to an object that is stored in the
     119             : // t object. We thus suppress the warning raised by cppcheck
     120   129092208 :   return (*static_cast<T*>(&t))(i,j);
     121             : }
     122             : 
     123             : template<class T,class C,class I,class J>
     124   129092208 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
     125   129092208 :   return Row(*this,i);
     126             : }
     127             : 
     128             : template<class T,class C,class I,class J>
     129     3523551 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
     130     3523551 :   return Const_row(*this,i);
     131             : }
     132             : 
     133             : }
     134             : 
     135             : 
     136             : #endif
     137             : 
     138             : 

Generated by: LCOV version 1.16