Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:05

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 // Author: Mathieu Karamitros
0028 
0029 /*
0030  * Compile time counter to use flags with switch and add new flags
0031  *
0032  *   - Usage 1
0033  *
0034  * class A {
0035  *  G4CT_COUNT_INIT(0)
0036  *  CT_COUNT(a)
0037  *  CT_COUNT(b)
0038  *  CT_COUNT(c)
0039  * };
0040  *
0041  * class B1 : public A{
0042  *  CT_COUNT(d)
0043  * };
0044  *
0045  * class B2 : public A{
0046  *  CT_COUNT(e)
0047  * };
0048  * class C : public B1{
0049  *  CT_COUNT(f)
0050  * };
0051  *
0052  * Result
0053  *  a = 0
0054  *  b = 1
0055  *  c = 2
0056  *  d & e = 3
0057  *  f = 4
0058  *
0059  *   - Usage 2
0060  *  namespace CounterNSpace{
0061  *    G4CT_COUNT_INIT(0)
0062  *    CT_COUNT(a)
0063  *    CT_COUNT(b)
0064  *    CT_COUNT(c)
0065  *  }
0066  *
0067  *  // extend
0068  *  namespace CounterNSpace{
0069  *    CT_COUNT(d)
0070  *    CT_COUNT(e)
0071  *    CT_COUNT(f)
0072  *  }
0073  */
0074 
0075 #ifndef G4CTCounter_h
0076 #define G4CTCounter_h
0077 
0078 template<int N>
0079 struct G4Number: public G4Number<N-1>{
0080   static constexpr int value=N;
0081 };
0082 
0083 template<>
0084 struct G4Number<0>{
0085   static constexpr int value=0;
0086 };
0087 
0088 //------------------------------------------------------------------------------
0089 
0090 #define G4CT_COUNT_INIT(init_value)     \
0091   static constexpr G4Number<init_value> \
0092    Counter(G4Number<init_value>) {      \
0093      return G4Number<init_value>();     \
0094    }
0095 
0096 // Allow overridable maximum enum depth by setting G4CT_MAX_COUNT
0097 #ifndef G4CT_MAX_COUNT
0098 #ifndef __NVCOMPILER
0099 // Maximum in Geant4 V11.0.0 is hardcoded to 255
0100 #define G4CT_MAX_COUNT 255
0101 #else
0102 // NVC++ compiler default template instantiation recursion limit is 64.
0103 // This can be changed by setting, e.g., "-Wc,--pending_instantiations=256"
0104 #define G4CT_MAX_COUNT 63
0105 #endif
0106 #endif
0107 
0108 #define G4CT_COUNT(flagName)                                                                  \
0109   static constexpr const int flagName = decltype(Counter(G4Number<G4CT_MAX_COUNT>{}))::value; \
0110   static constexpr G4Number<flagName + 1> Counter(G4Number<flagName + 1>)                     \
0111   {                                                                                           \
0112     static_assert(flagName + 1 < G4CT_MAX_COUNT, "Maximum enumeration count exeeded");        \
0113     return G4Number<flagName + 1>{};                                                          \
0114   }
0115 
0116 //------------------------------------------------------------------------------
0117 // On Win platforms, static functions must not be inlined, use the following
0118 // macros to separate definition and implementation of static function
0119 // to avoid potential crashes
0120 
0121 #define G4CT_COUNT_INIT_DEF(init_value) \
0122   static constexpr G4Number<init_value> \
0123    Counter(G4Number<init_value>);
0124 
0125 #define G4CT_COUNT_INIT_IMPL(enumName, init_value) \
0126   constexpr G4Number<init_value> \
0127    enumName::Counter(G4Number<init_value>){ \
0128      return G4Number<init_value>{}; \
0129    }
0130 
0131 #define G4CT_COUNT_DEF(flagName) \
0132   static constexpr const int flagName = \
0133    decltype(Counter(G4Number<G4CT_MAX_COUNT>{}))::value; \
0134   static constexpr G4Number<flagName + 1> \
0135    Counter(G4Number<flagName + 1>);
0136 
0137 #define G4CT_COUNT_IMPL(enumName, flagName) \
0138   constexpr G4Number<enumName::flagName + 1> \
0139    enumName::Counter(G4Number<enumName::flagName + 1>){ \
0140      return G4Number<enumName::flagName +1 >{}; \
0141    }
0142 
0143 //------------------------------------------------------------------------------
0144 
0145 #endif