Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/include/G4CTCounter.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 // Author: Mathieu Karamitros
 28 
 29 /*
 30  * Compile time counter to use flags with switch and add new flags
 31  *
 32  *   - Usage 1
 33  *
 34  * class A {
 35  *  G4CT_COUNT_INIT(0)
 36  *  CT_COUNT(a)
 37  *  CT_COUNT(b)
 38  *  CT_COUNT(c)
 39  * };
 40  *
 41  * class B1 : public A{
 42  *  CT_COUNT(d)
 43  * };
 44  *
 45  * class B2 : public A{
 46  *  CT_COUNT(e)
 47  * };
 48  * class C : public B1{
 49  *  CT_COUNT(f)
 50  * };
 51  *
 52  * Result
 53  *  a = 0
 54  *  b = 1
 55  *  c = 2
 56  *  d & e = 3
 57  *  f = 4
 58  *
 59  *   - Usage 2
 60  *  namespace CounterNSpace{
 61  *    G4CT_COUNT_INIT(0)
 62  *    CT_COUNT(a)
 63  *    CT_COUNT(b)
 64  *    CT_COUNT(c)
 65  *  }
 66  *
 67  *  // extend
 68  *  namespace CounterNSpace{
 69  *    CT_COUNT(d)
 70  *    CT_COUNT(e)
 71  *    CT_COUNT(f)
 72  *  }
 73  */
 74 
 75 #ifndef G4CTCounter_h
 76 #define G4CTCounter_h
 77 
 78 template<int N>
 79 struct G4Number: public G4Number<N-1>{
 80   static constexpr int value=N;
 81 };
 82 
 83 template<>
 84 struct G4Number<0>{
 85   static constexpr int value=0;
 86 };
 87 
 88 //------------------------------------------------------------------------------
 89 
 90 #define G4CT_COUNT_INIT(init_value)     \
 91   static constexpr G4Number<init_value> \
 92    Counter(G4Number<init_value>) {      \
 93      return G4Number<init_value>();     \
 94    }
 95 
 96 // Allow overridable maximum enum depth by setting G4CT_MAX_COUNT
 97 #ifndef G4CT_MAX_COUNT
 98 #ifndef __NVCOMPILER
 99 // Maximum in Geant4 V11.0.0 is hardcoded to 255
100 #define G4CT_MAX_COUNT 255
101 #else
102 // NVC++ compiler default template instantiation recursion limit is 64.
103 // This can be changed by setting, e.g., "-Wc,--pending_instantiations=256"
104 #define G4CT_MAX_COUNT 63
105 #endif
106 #endif
107 
108 #define G4CT_COUNT(flagName)                                                                  \
109   static constexpr const int flagName = decltype(Counter(G4Number<G4CT_MAX_COUNT>{}))::value; \
110   static constexpr G4Number<flagName + 1> Counter(G4Number<flagName + 1>)                     \
111   {                                                                                           \
112     static_assert(flagName + 1 < G4CT_MAX_COUNT, "Maximum enumeration count exeeded");        \
113     return G4Number<flagName + 1>{};                                                          \
114   }
115 
116 //------------------------------------------------------------------------------
117 // On Win platforms, static functions must not be inlined, use the following
118 // macros to separate definition and implementation of static function
119 // to avoid potential crashes
120 
121 #define G4CT_COUNT_INIT_DEF(init_value) \
122   static constexpr G4Number<init_value> \
123    Counter(G4Number<init_value>);
124 
125 #define G4CT_COUNT_INIT_IMPL(enumName, init_value) \
126   constexpr G4Number<init_value> \
127    enumName::Counter(G4Number<init_value>){ \
128      return G4Number<init_value>{}; \
129    }
130 
131 #define G4CT_COUNT_DEF(flagName) \
132   static constexpr const int flagName = \
133    decltype(Counter(G4Number<G4CT_MAX_COUNT>{}))::value; \
134   static constexpr G4Number<flagName + 1> \
135    Counter(G4Number<flagName + 1>);
136 
137 #define G4CT_COUNT_IMPL(enumName, flagName) \
138   constexpr G4Number<enumName::flagName + 1> \
139    enumName::Counter(G4Number<enumName::flagName + 1>){ \
140      return G4Number<enumName::flagName +1 >{}; \
141    }
142 
143 //------------------------------------------------------------------------------
144 
145 #endif
146