Changeset 24d6572 for src/Common


Ignore:
Timestamp:
Jun 12, 2023, 2:45:32 PM (3 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ast-experimental, master, stuck-waitfor-destruct
Children:
62d62db
Parents:
34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ast-experimental

Location:
src/Common
Files:
3 added
3 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • src/Common/CodeLocationTools.cpp

    r34b4268 r24d6572  
    128128    macro(FinallyClause, FinallyClause) \
    129129    macro(SuspendStmt, Stmt) \
     130    macro(WhenClause, WhenClause) \
    130131    macro(WaitForStmt, Stmt) \
    131132    macro(WaitForClause, WaitForClause) \
     133    macro(WaitUntilStmt, Stmt) \
    132134    macro(WithStmt, Decl) \
    133135    macro(NullStmt, NullStmt) \
     
    208210
    209211struct LeafKindVisitor : public ast::Visitor {
    210         LeafKind kind;
     212        LeafKind result;
    211213
    212214#define VISIT(node_type, return_type) \
    213215        const ast::return_type * visit( const ast::node_type * ) final { \
    214                 kind = LeafKind::node_type; \
     216                result = LeafKind::node_type; \
    215217                return nullptr; \
    216218        }
     
    222224
    223225LeafKind get_leaf_kind( ast::Node const * node ) {
    224         LeafKindVisitor visitor;
    225         node->accept( visitor );
    226         return visitor.kind;
     226        return ast::Pass<LeafKindVisitor>::read( node );
    227227}
    228228
  • src/Common/DeclStats.cpp

    r34b4268 r24d6572  
    2323#include <iostream>
    2424#include <map>
     25#include <sstream>
    2526#include <unordered_map>
    2627#include <unordered_set>
  • src/Common/Eval.cc

    r34b4268 r24d6572  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // utility.h --
     7// Eval.cc -- Evaluate parts of the ast at compile time.
    88//
    99// Author           : Richard C. Bilson
     
    1313// Update Count     : 119
    1414//
     15
     16#include "Eval.h"
    1517
    1618#include <utility> // for pair
  • src/Common/ResolvProtoDump.cpp

    r34b4268 r24d6572  
    1919#include <iostream>
    2020#include <set>
     21#include <sstream>
    2122#include <unordered_set>
    2223
     
    2627#include "AST/Type.hpp"
    2728#include "CodeGen/OperatorTable.h"
    28 #include "Common/utility.h"
    2929
    3030namespace {
  • src/Common/ScopedMap.h

    r34b4268 r24d6572  
    3737                template<typename N>
    3838                Scope(N && n) : map(), note(std::forward<N>(n)) {}
    39                
     39
    4040                Scope() = default;
    4141                Scope(const Scope &) = default;
     
    4646        typedef std::vector< Scope > ScopeList;
    4747
    48         ScopeList scopes; ///< scoped list of maps
     48        /// Scoped list of maps.
     49        ScopeList scopes;
    4950public:
    5051        typedef typename MapType::key_type key_type;
     
    5859        typedef typename MapType::const_pointer const_pointer;
    5960
    60         class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > {
    61         friend class ScopedMap;
    62         friend class const_iterator;
    63                 typedef typename ScopedMap::MapType::iterator wrapped_iterator;
    64                 typedef typename ScopedMap::ScopeList scope_list;
    65                 typedef typename scope_list::size_type size_type;
    66 
    67                 /// Checks if this iterator points to a valid item
    68                 bool is_valid() const {
    69                         return it != (*scopes)[level].map.end();
    70                 }
    71 
    72                 /// Increments on invalid
    73                 iterator & next_valid() {
    74                         if ( ! is_valid() ) { ++(*this); }
    75                         return *this;
    76                 }
    77 
    78                 /// Decrements on invalid
    79                 iterator & prev_valid() {
    80                         if ( ! is_valid() ) { --(*this); }
    81                         return *this;
    82                 }
    83 
    84                 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)
    85                         : scopes(&_scopes), it(_it), level(inLevel) {}
    86         public:
    87                 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
    88                 iterator & operator= (const iterator & that) {
    89                         scopes = that.scopes; level = that.level; it = that.it;
    90                         return *this;
    91                 }
    92 
    93                 reference operator* () { return *it; }
    94                 pointer operator-> () const { return it.operator->(); }
    95 
    96                 iterator & operator++ () {
    97                         if ( it == (*scopes)[level].map.end() ) {
    98                                 if ( level == 0 ) return *this;
    99                                 --level;
    100                                 it = (*scopes)[level].map.begin();
    101                         } else {
    102                                 ++it;
    103                         }
    104                         return next_valid();
    105                 }
    106                 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
    107 
    108                 iterator & operator-- () {
    109                         // may fail if this is the begin iterator; allowed by STL spec
    110                         if ( it == (*scopes)[level].map.begin() ) {
    111                                 ++level;
    112                                 it = (*scopes)[level].map.end();
    113                         }
    114                         --it;
    115                         return prev_valid();
    116                 }
    117                 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
    118 
    119                 bool operator== (const iterator & that) const {
    120                         return scopes == that.scopes && level == that.level && it == that.it;
    121                 }
    122                 bool operator!= (const iterator & that) const { return !( *this == that ); }
    123 
    124                 size_type get_level() const { return level; }
    125 
    126                 Note & get_note() { return (*scopes)[level].note; }
    127                 const Note & get_note() const { return (*scopes)[level].note; }
    128 
    129         private:
    130                 scope_list *scopes;
    131                 wrapped_iterator it;
    132                 size_type level;
    133         };
    134 
    135         class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
    136                                                      value_type > {
    137         friend class ScopedMap;
    138                 typedef typename ScopedMap::MapType::iterator wrapped_iterator;
    139                 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
    140                 typedef typename ScopedMap::ScopeList scope_list;
    141                 typedef typename scope_list::size_type size_type;
    142 
    143                 /// Checks if this iterator points to a valid item
    144                 bool is_valid() const {
    145                         return it != (*scopes)[level].map.end();
    146                 }
    147 
    148                 /// Increments on invalid
    149                 const_iterator & next_valid() {
    150                         if ( ! is_valid() ) { ++(*this); }
    151                         return *this;
    152                 }
    153 
    154                 /// Decrements on invalid
    155                 const_iterator & prev_valid() {
    156                         if ( ! is_valid() ) { --(*this); }
    157                         return *this;
    158                 }
    159 
    160                 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)
    161                         : scopes(&_scopes), it(_it), level(inLevel) {}
    162         public:
    163                 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
    164                 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
    165                 const_iterator & operator= (const iterator & that) {
    166                         scopes = that.scopes; level = that.level; it = that.it;
    167                         return *this;
    168                 }
    169                 const_iterator & operator= (const const_iterator & that) {
    170                         scopes = that.scopes; level = that.level; it = that.it;
    171                         return *this;
    172                 }
    173 
    174                 const_reference operator* () { return *it; }
    175                 const_pointer operator-> () { return it.operator->(); }
    176 
    177                 const_iterator & operator++ () {
    178                         if ( it == (*scopes)[level].map.end() ) {
    179                                 if ( level == 0 ) return *this;
    180                                 --level;
    181                                 it = (*scopes)[level].map.begin();
    182                         } else {
    183                                 ++it;
    184                         }
    185                         return next_valid();
    186                 }
    187                 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
    188 
    189                 const_iterator & operator-- () {
    190                         // may fail if this is the begin iterator; allowed by STL spec
    191                         if ( it == (*scopes)[level].map.begin() ) {
    192                                 ++level;
    193                                 it = (*scopes)[level].map.end();
    194                         }
    195                         --it;
    196                         return prev_valid();
    197                 }
    198                 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
    199 
    200                 bool operator== (const const_iterator & that) const {
    201                         return scopes == that.scopes && level == that.level && it == that.it;
    202                 }
    203                 bool operator!= (const const_iterator & that) const { return !( *this == that ); }
    204 
    205                 size_type get_level() const { return level; }
    206 
    207                 const Note & get_note() const { return (*scopes)[level].note; }
    208 
    209         private:
    210                 scope_list const *scopes;
    211                 wrapped_const_iterator it;
    212                 size_type level;
    213         };
     61        // Both iterator types are complete bidrectional iterators, see below.
     62        class iterator;
     63        class const_iterator;
    21464
    21565        /// Starts a new scope
     
    297147        }
    298148
    299         template< typename value_type_t >
    300         std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {
    301                 MapType & scope = (*at.scopes)[ at.level ].map;
    302                 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
    303                 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );
    304         }
    305 
    306149        template< typename value_t >
    307150        std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }
     
    324167        }
    325168
    326         iterator erase( iterator pos ) {
    327                 MapType & scope = (*pos.scopes)[ pos.level ].map;
    328                 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it );
    329                 iterator it( *pos.scopes, new_it, pos.level );
    330                 return it.next_valid();
     169        /// Erases element with key in the innermost scope that has it.
     170        size_type erase( const Key & key ) {
     171                for ( auto it = scopes.rbegin() ; it != scopes.rend() ; ++it ) {
     172                        size_type i = it->map.erase( key );
     173                        if ( 0 != i ) return i;
     174                }
     175                return 0;
    331176        }
    332177
     
    343188                return c;
    344189        }
     190
     191        bool contains( const Key & key ) const {
     192                return find( key ) != cend();
     193        }
     194};
     195
     196template<typename Key, typename Value, typename Note>
     197class ScopedMap<Key, Value, Note>::iterator :
     198                public std::iterator< std::bidirectional_iterator_tag, value_type > {
     199        friend class ScopedMap;
     200        friend class const_iterator;
     201        typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     202        typedef typename ScopedMap::ScopeList scope_list;
     203        typedef typename scope_list::size_type size_type;
     204
     205        /// Checks if this iterator points to a valid item
     206        bool is_valid() const {
     207                return it != (*scopes)[level].map.end();
     208        }
     209
     210        /// Increments on invalid
     211        iterator & next_valid() {
     212                if ( ! is_valid() ) { ++(*this); }
     213                return *this;
     214        }
     215
     216        /// Decrements on invalid
     217        iterator & prev_valid() {
     218                if ( ! is_valid() ) { --(*this); }
     219                return *this;
     220        }
     221
     222        iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)
     223                : scopes(&_scopes), it(_it), level(inLevel) {}
     224public:
     225        iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     226        iterator & operator= (const iterator & that) {
     227                scopes = that.scopes; level = that.level; it = that.it;
     228                return *this;
     229        }
     230
     231        reference operator* () { return *it; }
     232        pointer operator-> () const { return it.operator->(); }
     233
     234        iterator & operator++ () {
     235                if ( it == (*scopes)[level].map.end() ) {
     236                        if ( level == 0 ) return *this;
     237                        --level;
     238                        it = (*scopes)[level].map.begin();
     239                } else {
     240                        ++it;
     241                }
     242                return next_valid();
     243        }
     244        iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
     245
     246        iterator & operator-- () {
     247                // may fail if this is the begin iterator; allowed by STL spec
     248                if ( it == (*scopes)[level].map.begin() ) {
     249                        ++level;
     250                        it = (*scopes)[level].map.end();
     251                }
     252                --it;
     253                return prev_valid();
     254        }
     255        iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
     256
     257        bool operator== (const iterator & that) const {
     258                return scopes == that.scopes && level == that.level && it == that.it;
     259        }
     260        bool operator!= (const iterator & that) const { return !( *this == that ); }
     261
     262        size_type get_level() const { return level; }
     263
     264        Note & get_note() { return (*scopes)[level].note; }
     265        const Note & get_note() const { return (*scopes)[level].note; }
     266
     267private:
     268        scope_list *scopes;
     269        wrapped_iterator it;
     270        size_type level;
     271};
     272
     273template<typename Key, typename Value, typename Note>
     274class ScopedMap<Key, Value, Note>::const_iterator :
     275                public std::iterator< std::bidirectional_iterator_tag, value_type > {
     276        friend class ScopedMap;
     277        typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     278        typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
     279        typedef typename ScopedMap::ScopeList scope_list;
     280        typedef typename scope_list::size_type size_type;
     281
     282        /// Checks if this iterator points to a valid item
     283        bool is_valid() const {
     284                return it != (*scopes)[level].map.end();
     285        }
     286
     287        /// Increments on invalid
     288        const_iterator & next_valid() {
     289                if ( ! is_valid() ) { ++(*this); }
     290                return *this;
     291        }
     292
     293        /// Decrements on invalid
     294        const_iterator & prev_valid() {
     295                if ( ! is_valid() ) { --(*this); }
     296                return *this;
     297        }
     298
     299        const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)
     300                : scopes(&_scopes), it(_it), level(inLevel) {}
     301public:
     302        const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     303        const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     304        const_iterator & operator= (const iterator & that) {
     305                scopes = that.scopes; level = that.level; it = that.it;
     306                return *this;
     307        }
     308        const_iterator & operator= (const const_iterator & that) {
     309                scopes = that.scopes; level = that.level; it = that.it;
     310                return *this;
     311        }
     312
     313        const_reference operator* () { return *it; }
     314        const_pointer operator-> () { return it.operator->(); }
     315
     316        const_iterator & operator++ () {
     317                if ( it == (*scopes)[level].map.end() ) {
     318                        if ( level == 0 ) return *this;
     319                        --level;
     320                        it = (*scopes)[level].map.begin();
     321                } else {
     322                        ++it;
     323                }
     324                return next_valid();
     325        }
     326        const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
     327
     328        const_iterator & operator-- () {
     329                // may fail if this is the begin iterator; allowed by STL spec
     330                if ( it == (*scopes)[level].map.begin() ) {
     331                        ++level;
     332                        it = (*scopes)[level].map.end();
     333                }
     334                --it;
     335                return prev_valid();
     336        }
     337        const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
     338
     339        bool operator== (const const_iterator & that) const {
     340                return scopes == that.scopes && level == that.level && it == that.it;
     341        }
     342        bool operator!= (const const_iterator & that) const { return !( *this == that ); }
     343
     344        size_type get_level() const { return level; }
     345
     346        const Note & get_note() const { return (*scopes)[level].note; }
     347
     348private:
     349        scope_list const *scopes;
     350        wrapped_const_iterator it;
     351        size_type level;
    345352};
    346353
  • src/Common/SemanticError.h

    r34b4268 r24d6572  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May  4 14:08:26 2022
    13 // Update Count     : 35
     12// Last Modified On : Sat Feb 25 12:01:31 2023
     13// Update Count     : 37
    1414//
    1515
     
    5454
    5555constexpr WarningData WarningFormats[] = {
    56         {"self-assign"            , Severity::Warn    , "self assignment of expression: %s"                          },
    57         {"reference-conversion"   , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
    58         {"qualifiers-zero_t-one_t", Severity::Warn    , "questionable use of type qualifier %s with %s"              },
    59         {"aggregate-forward-decl" , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
    60         {"superfluous-decl"       , Severity::Warn    , "declaration does not allocate storage: %s"                  },
    61         {"superfluous-else"       , Severity::Warn    , "else clause never executed for empty loop conditional"      },
    62         {"gcc-attributes"         , Severity::Warn    , "invalid attribute: %s"                                      },
    63         {"c++-like-copy"          , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
     56        {"self-assign"              , Severity::Warn    , "self assignment of expression: %s"                          },
     57        {"reference-conversion"     , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
     58        {"qualifiers-zero_t-one_t"  , Severity::Warn    , "questionable use of type qualifier(s) with %s"              },
     59        {"aggregate-forward-decl"   , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
     60        {"superfluous-decl"         , Severity::Warn    , "declaration does not allocate storage: %s"                  },
     61        {"superfluous-else"         , Severity::Warn    , "else clause never executed for empty loop conditional"      },
     62        {"gcc-attributes"           , Severity::Warn    , "invalid attribute: %s"                                      },
     63        {"c++-like-copy"            , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
     64        {"depreciated-trait-syntax" , Severity::Warn    , "trait type-parameters are now specified using the forall clause" },
    6465};
    6566
     
    7374        GccAttributes,
    7475        CppCopy,
     76        DeprecTraitSyntax,
    7577        NUMBER_OF_WARNINGS, // This MUST be the last warning
    7678};
  • src/Common/module.mk

    r34b4268 r24d6572  
    2020        Common/CodeLocationTools.hpp \
    2121        Common/CodeLocationTools.cpp \
    22         Common/CompilerError.h \
    23         Common/Debug.h \
    2422        Common/DeclStats.hpp \
    2523        Common/DeclStats.cpp \
    2624        Common/ErrorObjects.h \
    2725        Common/Eval.cc \
     26        Common/Eval.h \
    2827        Common/Examine.cc \
    2928        Common/Examine.h \
     
    3130        Common/Indenter.h \
    3231        Common/Indenter.cc \
     32        Common/Iterate.hpp \
    3333        Common/PassVisitor.cc \
    3434        Common/PassVisitor.h \
     
    5252        Common/Stats/Time.cc \
    5353        Common/Stats/Time.h \
    54         Common/UnimplementedError.h \
     54        Common/ToString.hpp \
    5555        Common/UniqueName.cc \
    5656        Common/UniqueName.h \
  • src/Common/utility.h

    r34b4268 r24d6572  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // utility.h --
     7// utility.h -- General utilities used across the compiler.
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Apr 25 14:26:00 2022
    13 // Update Count     : 51
     12// Last Modified On : Fri Feb 17 15:25:00 2023
     13// Update Count     : 53
    1414//
    1515
     
    1919#include <cctype>
    2020#include <algorithm>
    21 #include <functional>
    2221#include <iostream>
    23 #include <iterator>
    2422#include <list>
    2523#include <memory>
    26 #include <sstream>
    2724#include <string>
    2825#include <type_traits>
    29 #include <utility>
    3026#include <vector>
    3127#include <cstring>                                                                              // memcmp
     
    4945                return 0;
    5046        } // if
    51 }
    52 
    53 template< typename T, typename U >
    54 struct maybeBuild_t {
    55         static T * doit( const U *orig ) {
    56                 if ( orig ) {
    57                         return orig->build();
    58                 } else {
    59                         return 0;
    60                 } // if
    61         }
    62 };
    63 
    64 template< typename T, typename U >
    65 static inline T * maybeBuild( const U *orig ) {
    66         return maybeBuild_t<T,U>::doit(orig);
    67 }
    68 
    69 template< typename T, typename U >
    70 static inline T * maybeMoveBuild( const U *orig ) {
    71         T* ret = maybeBuild<T>(orig);
    72         delete orig;
    73         return ret;
    7447}
    7548
     
    168141        splice( src, dst );
    169142        dst.swap( src );
    170 }
    171 
    172 template < typename T >
    173 void toString_single( std::ostream & os, const T & value ) {
    174         os << value;
    175 }
    176 
    177 template < typename T, typename... Params >
    178 void toString_single( std::ostream & os, const T & value, const Params & ... params ) {
    179         os << value;
    180         toString_single( os, params ... );
    181 }
    182 
    183 template < typename ... Params >
    184 std::string toString( const Params & ... params ) {
    185         std::ostringstream os;
    186         toString_single( os, params... );
    187         return os.str();
    188 }
    189 
    190 #define toCString( ... ) toString( __VA_ARGS__ ).c_str()
    191 
    192 // replace element of list with all elements of another list
    193 template< typename T >
    194 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
    195         typename std::list< T >::iterator next = pos; advance( next, 1 );
    196 
    197         //if ( next != org.end() ) {
    198         org.erase( pos );
    199         org.splice( next, with );
    200         //}
    201 
    202         return;
    203 }
    204 
    205 // replace range of a list with a single element
    206 template< typename T >
    207 void replace( std::list< T > &org, typename std::list< T >::iterator begin, typename std::list< T >::iterator end, const T & with ) {
    208         org.insert( begin, with );
    209         org.erase( begin, end );
    210143}
    211144
     
    236169}
    237170
    238 template< typename... Args >
    239 auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) {
    240   return zipWith(std::forward<Args>(args)..., std::make_pair);
    241 }
    242 
    243 template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction >
    244 void zipWith( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out, BinFunction func ) {
    245         while ( b1 != e1 && b2 != e2 )
    246                 *out++ = func(*b1++, *b2++);
    247 }
    248 
    249 // it's nice to actually be able to increment iterators by an arbitrary amount
    250 template< class InputIt, class Distance >
    251 InputIt operator+( InputIt it, Distance n ) {
    252         advance(it, n);
    253         return it;
    254 }
    255 
    256 template< typename T >
    257 void warn_single( const T & arg ) {
    258         std::cerr << arg << std::endl;
    259 }
    260 
    261 template< typename T, typename... Params >
    262 void warn_single(const T & arg, const Params & ... params ) {
    263         std::cerr << arg;
    264         warn_single( params... );
    265 }
    266 
    267 template< typename... Params >
    268 void warn( const Params & ... params ) {
    269         std::cerr << "Warning: ";
    270         warn_single( params... );
    271 }
    272 
    273171// determines if pref is a prefix of str
    274172static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) {
    275173        if ( pref.size() > str.size() ) return false;
    276     return 0 == memcmp( str.c_str() + start, pref.c_str(), pref.size() );
    277         // return prefix == full.substr(0, prefix.size()); // for future, requires c++17
    278 }
    279 
    280 // -----------------------------------------------------------------------------
    281 // Ref Counted Singleton class
    282 // Objects that inherit from this class will have at most one reference to it
    283 // but if all references die, the object will be deleted.
    284 
    285 template< typename ThisType >
    286 class RefCountSingleton {
    287   public:
    288         static std::shared_ptr<ThisType> get() {
    289                 if( global_instance.expired() ) {
    290                         std::shared_ptr<ThisType> new_instance = std::make_shared<ThisType>();
    291                         global_instance = new_instance;
    292                         return std::move(new_instance);
    293                 }
    294                 return global_instance.lock();
    295         }
    296   private:
    297         static std::weak_ptr<ThisType> global_instance;
    298 };
    299 
    300 template< typename ThisType >
    301 std::weak_ptr<ThisType> RefCountSingleton<ThisType>::global_instance;
     174        return pref == str.substr(start, pref.size());
     175}
    302176
    303177// -----------------------------------------------------------------------------
     
    356230        ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } }
    357231};
    358 
    359 // -----------------------------------------------------------------------------
    360 // Helper struct and function to support
    361 // for ( val : reverseIterate( container ) ) {}
    362 // syntax to have a for each that iterates backwards
    363 
    364 template< typename T >
    365 struct reverse_iterate_t {
    366         T& ref;
    367 
    368         reverse_iterate_t( T & ref ) : ref(ref) {}
    369 
    370         // this does NOT work on const T!!!
    371         // typedef typename T::reverse_iterator iterator;
    372         auto begin() { return ref.rbegin(); }
    373         auto end() { return ref.rend(); }
    374 };
    375 
    376 template< typename T >
    377 reverse_iterate_t< T > reverseIterate( T & ref ) {
    378         return reverse_iterate_t< T >( ref );
    379 }
    380 
    381 template< typename T >
    382 struct enumerate_t {
    383         template<typename val_t>
    384         struct value_t {
    385                 val_t & val;
    386                 size_t idx;
    387         };
    388 
    389         template< typename iter_t, typename val_t >
    390         struct iterator_t {
    391                 iter_t it;
    392                 size_t idx;
    393 
    394                 iterator_t( iter_t _it, size_t _idx ) : it(_it), idx(_idx) {}
    395 
    396                 value_t<val_t> operator*() const { return value_t<val_t>{ *it, idx }; }
    397 
    398                 bool operator==(const iterator_t & o) const { return o.it == it; }
    399                 bool operator!=(const iterator_t & o) const { return o.it != it; }
    400 
    401                 iterator_t & operator++() {
    402                         it++;
    403                         idx++;
    404                         return *this;
    405                 }
    406 
    407                 using difference_type   = typename std::iterator_traits< iter_t >::difference_type;
    408                 using value_type        = value_t<val_t>;
    409                 using pointer           = value_t<val_t> *;
    410                 using reference         = value_t<val_t> &;
    411                 using iterator_category = std::forward_iterator_tag;
    412         };
    413 
    414         T & ref;
    415 
    416         using iterator = iterator_t< typename T::iterator, typename T::value_type >;
    417         using const_iterator = iterator_t< typename T::const_iterator, const typename T::value_type >;
    418 
    419         iterator begin() { return iterator( ref.begin(), 0 ); }
    420         iterator end()   { return iterator( ref.end(), ref.size() ); }
    421 
    422         const_iterator begin() const { return const_iterator( ref.cbegin(), 0 ); }
    423         const_iterator end()   const { return const_iterator( ref.cend(), ref.size() ); }
    424 
    425         const_iterator cbegin() const { return const_iterator( ref.cbegin(), 0 ); }
    426         const_iterator cend()   const { return const_iterator( ref.cend(), ref.size() ); }
    427 };
    428 
    429 template< typename T >
    430 enumerate_t<T> enumerate( T & ref ) {
    431         return enumerate_t< T >{ ref };
    432 }
    433 
    434 template< typename T >
    435 const enumerate_t< const T > enumerate( const T & ref ) {
    436         return enumerate_t< const T >{ ref };
    437 }
    438 
    439 template< typename OutType, typename Range, typename Functor >
    440 OutType map_range( const Range& range, Functor&& functor ) {
    441         OutType out;
    442 
    443         std::transform(
    444                 begin( range ),
    445                 end( range ),
    446                 std::back_inserter( out ),
    447                 std::forward< Functor >( functor )
    448         );
    449 
    450         return out;
    451 }
    452 
    453 // -----------------------------------------------------------------------------
    454 // Helper struct and function to support:
    455 // for ( auto val : group_iterate( container1, container2, ... ) ) { ... }
    456 // This iteraters through multiple containers of the same size.
    457 
    458 template<typename... Args>
    459 class group_iterate_t {
    460         using Iterables = std::tuple<Args...>;
    461         Iterables iterables;
    462 
    463         // Getting the iterator and value types this way preserves const.
    464         template<size_t I> using Iter = decltype(std::get<I>(iterables).begin());
    465         template<size_t I> using Data = decltype(*std::get<I>(iterables).begin());
    466         template<typename> struct base_iterator;
    467 
    468         // This inner template puts the sequence of `0, 1, ... sizeof...(Args)-1`
    469         // into a pack. These are the indexes into the tuples, so unpacking can
    470         // go over each element of the tuple.
    471         // The std::integer_sequence is just used to build that sequence.
    472         // A library reference will probably explain it better than I can.
    473         template<std::size_t... Indices>
    474         struct base_iterator<std::integer_sequence<std::size_t, Indices...>> {
    475                 using value_type = std::tuple< Data<Indices>... >;
    476                 std::tuple<Iter<Indices>...> iterators;
    477 
    478                 base_iterator( Iter<Indices>... is ) : iterators( is... ) {}
    479                 base_iterator operator++() {
    480                         return base_iterator( ++std::get<Indices>( iterators )... );
    481                 }
    482                 bool operator!=( const base_iterator& other ) const {
    483                         return iterators != other.iterators;
    484                 }
    485                 value_type operator*() const {
    486                         return std::tie( *std::get<Indices>( iterators )... );
    487                 }
    488 
    489                 static base_iterator make_begin( Iterables & data ) {
    490                         return base_iterator( std::get<Indices>( data ).begin()... );
    491                 }
    492                 static base_iterator make_end( Iterables & data ) {
    493                         return base_iterator( std::get<Indices>( data ).end()... );
    494                 }
    495         };
    496 
    497 public:
    498         group_iterate_t( const Args &... args ) : iterables( args... ) {}
    499 
    500         using iterator = base_iterator<decltype(
    501                 std::make_integer_sequence<std::size_t, sizeof...(Args)>())>;
    502 
    503         iterator begin() { return iterator::make_begin( iterables ); }
    504         iterator end() { return iterator::make_end( iterables ); }
    505 };
    506 
    507 // Helpers for the bounds checks (the non-varatic part of group_iterate):
    508 static inline void runGroupBoundsCheck(size_t size0, size_t size1) {
    509         assertf( size0 == size1,
    510                 "group iteration requires containers of the same size: <%zd, %zd>.",
    511                 size0, size1 );
    512 }
    513 
    514 static inline void runGroupBoundsCheck(size_t size0, size_t size1, size_t size2) {
    515         assertf( size0 == size1 && size1 == size2,
    516                 "group iteration requires containers of the same size: <%zd, %zd, %zd>.",
    517                 size0, size1, size2 );
    518 }
    519 
    520 /// Performs bounds check to ensure that all arguments are of the same length.
    521 template< typename... Args >
    522 group_iterate_t<Args...> group_iterate( Args &&... args ) {
    523         runGroupBoundsCheck( args.size()... );
    524         return group_iterate_t<Args...>( std::forward<Args>( args )... );
    525 }
    526 
    527 /// Does not perform a bounds check - requires user to ensure that iteration terminates when appropriate.
    528 template< typename... Args >
    529 group_iterate_t<Args...> unsafe_group_iterate( Args &&... args ) {
    530         return group_iterate_t<Args...>( std::forward<Args>( args )... );
    531 }
    532 
    533 // -----------------------------------------------------------------------------
    534 // Helper struct and function to support
    535 // for ( val : lazy_map( container1, f ) ) {}
    536 // syntax to have a for each that iterates a container, mapping each element by applying f
    537 template< typename T, typename Func >
    538 struct lambda_iterate_t {
    539         const T & ref;
    540         std::function<Func> f;
    541 
    542         struct iterator {
    543                 typedef decltype(begin(ref)) Iter;
    544                 Iter it;
    545                 std::function<Func> f;
    546                 iterator( Iter it, std::function<Func> f ) : it(it), f(f) {}
    547                 iterator & operator++() {
    548                         ++it; return *this;
    549                 }
    550                 bool operator!=( const iterator &other ) const { return it != other.it; }
    551                 auto operator*() const -> decltype(f(*it)) { return f(*it); }
    552         };
    553 
    554         lambda_iterate_t( const T & ref, std::function<Func> f ) : ref(ref), f(f) {}
    555 
    556         auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); }
    557         auto end() const   -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); }
    558 };
    559 
    560 template< typename... Args >
    561 lambda_iterate_t<Args...> lazy_map( const Args &... args ) {
    562         return lambda_iterate_t<Args...>( args...);
    563 }
    564232
    565233// -----------------------------------------------------------------------------
     
    583251} // ilog2
    584252
    585 // -----------------------------------------------------------------------------
    586 /// evaluates expr as a long long int. If second is false, expr could not be evaluated
    587 std::pair<long long int, bool> eval(const Expression * expr);
    588 
    589 namespace ast {
    590         class Expr;
    591 }
    592 
    593 std::pair<long long int, bool> eval(const ast::Expr * expr);
    594 
    595 // -----------------------------------------------------------------------------
    596 /// Reorders the input range in-place so that the minimal-value elements according to the
    597 /// comparator are in front;
    598 /// returns the iterator after the last minimal-value element.
    599 template<typename Iter, typename Compare>
    600 Iter sort_mins( Iter begin, Iter end, Compare& lt ) {
    601         if ( begin == end ) return end;
    602 
    603         Iter min_pos = begin;
    604         for ( Iter i = begin + 1; i != end; ++i ) {
    605                 if ( lt( *i, *min_pos ) ) {
    606                         // new minimum cost; swap into first position
    607                         min_pos = begin;
    608                         std::iter_swap( min_pos, i );
    609                 } else if ( ! lt( *min_pos, *i ) ) {
    610                         // duplicate minimum cost; swap into next minimum position
    611                         ++min_pos;
    612                         std::iter_swap( min_pos, i );
    613                 }
    614         }
    615         return ++min_pos;
    616 }
    617 
    618 template<typename Iter, typename Compare>
    619 inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) {
    620         return sort_mins( begin, end, lt );
    621 }
    622 
    623 /// sort_mins defaulted to use std::less
    624 template<typename Iter>
    625 inline Iter sort_mins( Iter begin, Iter end ) {
    626         return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} );
    627 }
    628 
    629253// Local Variables: //
    630254// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.