Ignore:
Timestamp:
May 28, 2024, 11:38:25 AM (6 weeks ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
91b9e10
Parents:
66286aa
Message:

Simplified the visit children guard to use a ValueGuardPtr?. For consistency, so all three guards use the same pattern, I also updated the value guard, which is a side ways step in complexity (although less of it is under macros now).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.proto.hpp

    r66286aa r96c04e4  
    4040typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t;
    4141
    42 /// Implementation of the guard value
    43 /// Created inside the visit scope
    44 class guard_value {
     42/// Replaces guards we don't want to use.
     43struct empty_guard {
     44};
     45
     46/// Implementation of the value guard. Created inside the visit scope.
     47class value_guard {
    4548public:
    4649        /// Push onto the cleanup
    47         guard_value( at_cleanup_t * at_cleanup ) {
    48                 if( at_cleanup ) {
    49                         *at_cleanup = [this]( cleanup_func_t && func, void* val ) {
    50                                 push( std::move( func ), val );
    51                         };
    52                 }
    53         }
    54 
    55         ~guard_value() {
     50        value_guard( at_cleanup_t & at_cleanup ) {
     51                at_cleanup = [this]( cleanup_func_t && func, void* val ) {
     52                        push( std::move( func ), val );
     53                };
     54        }
     55
     56        ~value_guard() {
    5657                while( !cleanups.empty() ) {
    5758                        auto& cleanup = cleanups.top();
     
    7475
    7576        std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
    76 };
    77 
    78 // Guard structure implementation for whether or not children should be visited
    79 class visit_children_guard {
    80 public:
    81 
    82         visit_children_guard( bool * ref ) :
    83                 m_ref( ref ), m_val( true )
    84         {
    85                 if ( m_ref ) { m_val = *m_ref; *m_ref = true; }
    86         }
    87 
    88         ~visit_children_guard() {
    89                 if ( m_ref ) { *m_ref = m_val; }
    90         }
    91 
    92 private:
    93         bool * m_ref;
    94         bool   m_val;
    9577};
    9678
     
    280262FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > )
    281263FIELD_PTR( visit_children, bool )
    282 FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    283264FIELD_PTR( visitor, ast::Pass<core_t> * const )
    284265FIELD_PTR( translationUnit, const TranslationUnit * )
     
    314295}
    315296
     297// These are the guards declared at the beginning of a visit.
     298// They are replaced with empty objects when not used.
     299
    316300template< typename core_t, typename node_t >
    317 static auto make_location_guard( core_t & core, node_t * node, int )
     301static inline auto make_location_guard( core_t & core, node_t * node, int )
    318302                -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) {
    319303        ValueGuardPtr<const CodeLocation *> guard( &core.location );
     
    323307
    324308template< typename core_t, typename node_t >
    325 static auto make_location_guard( core_t &, node_t *, long ) -> int {
    326         return 0;
     309static inline empty_guard make_location_guard( core_t &, node_t *, long ) {
     310        return empty_guard();
     311}
     312
     313template< typename core_t >
     314static inline auto make_visit_children_guard( core_t & core, int )
     315                -> decltype( ValueGuardPtr<bool>( &core.visit_children ) ) {
     316        ValueGuardPtr<bool> guard( &core.visit_children );
     317        core.visit_children = true;
     318        return guard;
     319}
     320
     321template< typename core_t >
     322static inline empty_guard make_visit_children_guard( core_t &, long ) {
     323        return empty_guard();
     324}
     325
     326template< typename core_t >
     327static inline auto make_value_guard( core_t & core, int )
     328                -> decltype( value_guard( core.at_cleanup ) ) {
     329        // Requires guaranteed copy elision:
     330        return value_guard( core.at_cleanup );
     331}
     332
     333template< typename core_t >
     334static inline empty_guard make_value_guard( core_t &, long ) {
     335        return empty_guard();
    327336}
    328337
Note: See TracChangeset for help on using the changeset viewer.