G4AnyType.hh

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id: G4UImessenger.hh,v 1.9 2006-06-29 19:08:19 gunter Exp $
00028 //
00029 // See http://www.boost.org/libs/any for Documentation.
00030 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00031 //
00032 // Permission to use, copy, modify, and distribute this software for any
00033 // purpose is hereby granted without fee, provided that this copyright and
00034 // permissions notice appear in all copies and derivatives.
00035 //
00036 // This software is provided "as is" without express or implied warranty.
00037 // What:  variant At boost::any
00038 // who:   contributed by Kevlin Henney,
00039 //        with features contributed and bugs found by
00040 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
00041 // when:  July 2001
00042 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
00043 
00044 #ifndef G4AnyType_h
00045 #define G4AnyType_h 1
00046 
00047 #include <algorithm>
00048 #include <typeinfo>
00049 #include <iostream>
00050 #include <sstream>
00051 
00052 class G4String;
00053 namespace CLHEP {
00054   class Hep3Vector;
00055 }
00056 
00061 class  G4AnyType {  
00062 public:
00064   G4AnyType():
00065   fContent(0) {}
00066   
00068   template <typename ValueType> G4AnyType(ValueType &value):
00069   fContent(new Ref<ValueType>(value)) {}
00070   
00072   G4AnyType(const G4AnyType &other):
00073   fContent(other.fContent ? other.fContent->Clone() : 0) {}
00074   
00076   ~G4AnyType() {
00077     delete fContent;
00078   }
00079   
00081   operator bool() {
00082     return !Empty();
00083   }
00085   G4AnyType& Swap(G4AnyType& rhs) {
00086     std::swap(fContent, rhs.fContent);
00087     return *this;
00088   }
00090   template <typename ValueType> G4AnyType& operator =(const ValueType& rhs) {
00091     G4AnyType(rhs).Swap(*this);
00092     return *this;
00093   }
00095   G4AnyType& operator =(const G4AnyType& rhs) {
00096     G4AnyType(rhs).Swap(*this);
00097     return *this;
00098   }
00100   bool Empty() const {
00101     return !fContent;
00102   }
00104   const std::type_info& TypeInfo() const {
00105     return fContent ? fContent->TypeInfo() : typeid(void);
00106   }
00108   void* Address() const {
00109     return fContent ? fContent->Address() : 0;
00110   }
00112   std::string ToString() const {
00113     return fContent->ToString();
00114   }
00116   void FromString(const std::string& val) {
00117     fContent->FromString(val);
00118   }
00119 private:
00123   class Placeholder {
00124   public:
00126     Placeholder() {}
00128     virtual ~Placeholder() {}
00130     virtual const std::type_info& TypeInfo() const = 0;
00132     virtual Placeholder* Clone() const = 0;
00134     virtual void* Address() const = 0;
00136     virtual std::string ToString() const = 0;
00138     virtual void FromString(const std::string& val) = 0;
00139   };
00140   
00141   template <typename ValueType> class Ref: public Placeholder {
00142   public:
00144     Ref(ValueType& value): fRef(value) {}
00146     virtual const std::type_info& TypeInfo() const {
00147       return typeid(ValueType);
00148     }
00150     virtual Placeholder* Clone() const {
00151       return new Ref(fRef);
00152     }
00154     virtual void* Address() const {
00155       return (void*) (&fRef);
00156     }
00158     virtual std::string ToString() const {
00159       std::stringstream s;
00160       s << fRef;
00161       return s.str();
00162     }
00164     virtual void FromString(const std::string& val) {
00165       std::stringstream s(val);
00166       s >> fRef;
00167     }
00169     ValueType& fRef;
00170   };
00172   template <typename ValueType> friend ValueType* any_cast(G4AnyType*);
00174   Placeholder* fContent;
00175 };
00176 
00181 template<> void G4AnyType::Ref<bool>::FromString(const std::string& val);
00182 template<> void G4AnyType::Ref<G4String>::FromString(const std::string& val);
00183 template<> void G4AnyType::Ref<CLHEP::Hep3Vector>::FromString(const std::string& val);
00184 
00189 class G4BadAnyCast: public std::bad_cast {
00190 public:
00192   G4BadAnyCast() {}
00193   
00195   virtual const char* what() const throw() {
00196     return "G4BadAnyCast: failed conversion using any_cast";
00197   }
00198 };
00199 
00201 template <typename ValueType> ValueType* any_cast(G4AnyType* operand) {
00202   return operand && operand->TypeInfo() == typeid(ValueType)
00203   ? &static_cast<G4AnyType::Ref<ValueType>*>(operand->fContent)->fRef : 0;
00204 }
00206 template <typename ValueType> const ValueType* any_cast(const G4AnyType* operand) {
00207   return any_cast<ValueType>(const_cast<G4AnyType*>(operand));
00208 }
00210 template <typename ValueType> ValueType any_cast(const G4AnyType& operand) {
00211   const ValueType* result = any_cast<ValueType>(&operand);
00212   if (!result) {
00213     throw G4BadAnyCast();
00214   }
00215   return *result;
00216 }
00217 
00218 #endif

Generated on Mon May 27 17:47:41 2013 for Geant4 by  doxygen 1.4.7