Changeset 13d5a9 for src


Ignore:
Timestamp:
Apr 26, 2010, 1:49:59 PM (15 years ago)
Author:
Tillmann Crueger <crueger@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
5f612ee
Parents:
8bb2fd
Message:

Added macros that allow type safe casting using the Assert mechanism

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/small_actions.cpp

    r8bb2fd r13d5a9  
    5555
    5656Action::state_ptr ChangeMoleculeNameAction::performUndo(Action::state_ptr _state) {
    57   ChangeMoleculeNameState *state = dynamic_cast<ChangeMoleculeNameState*>(_state.get());
    58   ASSERT(state,"State passed to ChangeMoleculeNameAction::performUndo did not have correct type");
     57  ChangeMoleculeNameState *state = assert_cast<ChangeMoleculeNameState*>(_state.get());
    5958
    6059  string newName = state->mol->getName();
  • src/Helpers/Assert.cpp

    r8bb2fd r13d5a9  
    4848Action _my_assert::defaultAction = Ask;
    4949std::vector<Assert::hook_t> _my_assert::hooks;
     50
     51std::map<std::string,bool> _wrapper::ignores;
     52const char* _wrapper::message_ptr = "source pointer did not point to object of desired type";
     53const char* _wrapper::message_ref = "source reference did not contain object of desired type";
     54
     55
    5056
    5157bool _my_assert::check(const bool res,
  • src/Helpers/Assert.hpp

    r8bb2fd r13d5a9  
    99#define ASSERT_HPP_
    1010
     11#include<sstream>
    1112#include<string>
     13#include<iostream>
    1214#include<vector>
     15#include<map>
    1316
    1417/**
     
    215218 */
    216219
     220#ifndef NDEBUG
     221  #ifndef STRINGIFY
     222    #define STRINGIFY(x) #x
     223  #endif
     224
     225  #ifdef __GNUC__
     226    // on gcc we know how to exit to the Debugger
     227    #define DEBUG_BREAK __builtin_trap()
     228  #else
     229    #define DEBUG_BREAK exit(1)
     230  #endif
     231
     232  #define ASSERT(condition,message) \
     233    do{\
     234      static bool ignore = false;\
     235      if(!ignore){\
     236        if(Assert::_my_assert::check((condition),STRINGIFY(condition),(message),\
     237                                     __FILE__,__LINE__,ignore)){\
     238          Assert::_my_assert::doHooks();\
     239          DEBUG_BREAK;\
     240        }\
     241      } \
     242    }while(0)
     243
     244  #define ASSERT_NOCATCH(message) \
     245                catch(Assert::AssertionFailure&){throw;}\
     246                catch(...){\
     247                  static bool ignore = false; \
     248                  if(!ignore){\
     249                          if(Assert::_my_assert::check(false,"Exception caught",(message),__FILE__,__LINE__,ignore)){\
     250                            Assert::_my_assert::doHooks();\
     251          DEBUG_BREAK;\
     252                          }\
     253                  }\
     254                } do{(void)(0);}while(0)
     255
     256  #define assert_cast Assert::_wrapper(__LINE__,__FILE__)._convert
     257
     258  #define ASSERT_DO(action)    do{Assert::_my_assert::setDefault(action);}while(0)
     259  #define ASSERT_HOOK(hook)    do{Assert::_my_assert::addHook(hook);}while(0)
     260  #define ASSERT_UNHOOK(hook)  do{Assert::_my_assert::removeHook(hook);}while(0)
     261  #define ASSERT_DEFAULT       (Assert::_myAssert::printDefault())
     262#else
     263  // we need to do something, so this is the usual solution (e.g. assert.h)
     264  #define ASSERT(condition,message) (void)(0)
     265  #define ASSERT_NOCATCH(message)   catch(...) {throw;} do{(void)(0);}while(0)
     266  #define assert_cast static_cast
     267  #define ASSERT_DO(action)         (void)(0)
     268  #define ASSERT_HOOK(hook)         (void)(0)
     269  #define ASSERT_UNHOOK(hook)       (void)(0)
     270  #define ASSERT_DEFAULT            std::string("Deactivated")
     271#endif
     272
    217273namespace Assert{
    218274
     
    238294    std::string message;
    239295  };
     296
     297  //! @cond
     298#ifndef NDEBUG
     299    class _my_assert{
     300    public:
     301      static bool check(const bool res,
     302                        const char* condition,
     303                        const char* message,
     304                        const char* filename,
     305                        const int line,
     306                        bool& ignore);
     307      static void addHook(Assert::hook_t hook);
     308      static void removeHook(Assert::hook_t hook);
     309      static void doHooks();
     310      static void setDefault(Assert::Action);
     311      static Assert::Action getDefault();
     312      static std::string printDefault();
     313    private:
     314      static Assert::Action defaultAction;
     315      static std::vector<Assert::hook_t> hooks;
     316    };
     317
     318
     319  class _wrapper{
     320  public:
     321    _wrapper(int _line,const char* _file) :
     322      line(_line),
     323      file(_file)
     324      {}
     325
     326    // Overloaded template for pointers
     327    template<typename target,typename source>
     328    target _convert(source *src){
     329      std::stringstream sstr;
     330      sstr << file << ":" << line;
     331      bool &ignore = ignores[sstr.str()];
     332
     333      if(!ignore){
     334        if(_my_assert::check(dynamic_cast<target>(src)==static_cast<target>(src),"type-safe typecast",
     335                                       message_ptr,file,line,ignore)){
     336          _my_assert::doHooks();
     337          DEBUG_BREAK;
     338        }
     339      }
     340      return static_cast<target>(src);
     341    }
     342
     343    // Overloaded template for references
     344    template<typename target, typename source>
     345    target _convert(source &src){
     346            std::stringstream sstr;
     347      sstr << file << ":" << line;
     348      bool &ignore = ignores[sstr.str()];
     349
     350      try{
     351        target res =dynamic_cast<target>(src);
     352        return res;
     353      }
     354      catch(...){
     355        if(!ignore){
     356          if(_my_assert::check(0,"type-safe typecast",message_ref,file,line,ignore)){
     357            _my_assert::doHooks();
     358            DEBUG_BREAK;
     359          }
     360        }
     361      }
     362      // The error was ignored. Just return whatever a static_cast would do
     363      return static_cast<target>(src);
     364    }
     365  private:
     366    int line;
     367    const char *file;
     368    static std::map<std::string,bool> ignores;
     369    // this avoids duplication of the strings when templates are instantiated
     370    static const char* message_ptr;
     371    static const char* message_ref;
     372  };
     373#endif
     374  //! @endcond
    240375}
    241376
    242 #ifndef NDEBUG
    243   #ifndef STRINGIFY
    244     #define STRINGIFY(x) #x
    245   #endif
    246 
    247   #ifdef __GNUC__
    248     // on gcc we know how to exit to the Debugger
    249     #define DEBUG_BREAK __builtin_trap()
    250   #else
    251     #define DEBUG_BREAK exit(1)
    252   #endif
    253 
    254   #define ASSERT(condition,message) \
    255     do{\
    256       static bool ignore = false;\
    257       if(!ignore){\
    258         if(_my_assert::check((condition),STRINGIFY(condition),(message),__FILE__,__LINE__,ignore)){\
    259           _my_assert::doHooks();\
    260           DEBUG_BREAK;\
    261         }\
    262       } \
    263     }while(0)
    264 
    265   #define ASSERT_NOCATCH(message) \
    266                 catch(Assert::AssertionFailure&){throw;}\
    267                 catch(...){\
    268                   static bool ignore = false; \
    269                   _my_assert::check(false,"Exception caught",(message),__FILE__,__LINE__,ignore);\
    270                 } do{(void)(0);}while(0)
    271 
    272   #define ASSERT_DO(action)    do{_my_assert::setDefault(action);}while(0)
    273   #define ASSERT_HOOK(hook)    do{_my_assert::addHook(hook);}while(0)
    274   #define ASSERT_UNHOOK(hook)  do{_my_assert::removeHook(hook);}while(0)
    275   #define ASSERT_DEFAULT       (_myAssert::printDefault())
    276 #else
    277   // we need to do something, so this is the usual solution (e.g. assert.h)
    278   #define ASSERT(condition,message) (void)(0)
    279   #define ASSERT_NOCATCH(message)   catch(...) {throw;} do{(void)(0);}while(0)
    280   #define ASSERT_DO(action)         (void)(0)
    281   #define ASSERT_HOOK(hook)         (void)(0)
    282   #define ASSERT_UNHOOK(hook)       (void)(0)
    283   #define ASSERT_DEFAULT            std::string("Deactivated")
    284 #endif
    285 
    286 //! @cond
    287 class _my_assert{
    288 public:
    289   static bool check(const bool res,
    290                     const char* condition,
    291                     const char* message,
    292                     const char* filename,
    293                     const int line,
    294                     bool& ignore);
    295   static void addHook(Assert::hook_t hook);
    296   static void removeHook(Assert::hook_t hook);
    297   static void doHooks();
    298   static void setDefault(Assert::Action);
    299   static Assert::Action getDefault();
    300   static std::string printDefault();
    301 private:
    302   static Assert::Action defaultAction;
    303   static std::vector<Assert::hook_t> hooks;
    304 };
    305 //! @endcond
     377
    306378
    307379
Note: See TracChangeset for help on using the changeset viewer.