Changeset 24d6572 for src/Common
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (3 years ago)
- 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. - Location:
- src/Common
- Files:
-
- 3 added
- 3 deleted
- 8 edited
-
CodeLocationTools.cpp (modified) (3 diffs)
-
CompilerError.h (deleted)
-
Debug.h (deleted)
-
DeclStats.cpp (modified) (1 diff)
-
Eval.cc (modified) (2 diffs)
-
Eval.h (added)
-
Iterate.hpp (added)
-
ResolvProtoDump.cpp (modified) (2 diffs)
-
ScopedMap.h (modified) (6 diffs)
-
SemanticError.h (modified) (3 diffs)
-
ToString.hpp (added)
-
UnimplementedError.h (deleted)
-
module.mk (modified) (3 diffs)
-
utility.h (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Common/CodeLocationTools.cpp
r34b4268 r24d6572 128 128 macro(FinallyClause, FinallyClause) \ 129 129 macro(SuspendStmt, Stmt) \ 130 macro(WhenClause, WhenClause) \ 130 131 macro(WaitForStmt, Stmt) \ 131 132 macro(WaitForClause, WaitForClause) \ 133 macro(WaitUntilStmt, Stmt) \ 132 134 macro(WithStmt, Decl) \ 133 135 macro(NullStmt, NullStmt) \ … … 208 210 209 211 struct LeafKindVisitor : public ast::Visitor { 210 LeafKind kind;212 LeafKind result; 211 213 212 214 #define VISIT(node_type, return_type) \ 213 215 const ast::return_type * visit( const ast::node_type * ) final { \ 214 kind= LeafKind::node_type; \216 result = LeafKind::node_type; \ 215 217 return nullptr; \ 216 218 } … … 222 224 223 225 LeafKind 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 ); 227 227 } 228 228 -
src/Common/DeclStats.cpp
r34b4268 r24d6572 23 23 #include <iostream> 24 24 #include <map> 25 #include <sstream> 25 26 #include <unordered_map> 26 27 #include <unordered_set> -
src/Common/Eval.cc
r34b4268 r24d6572 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // utility.h --7 // Eval.cc -- Evaluate parts of the ast at compile time. 8 8 // 9 9 // Author : Richard C. Bilson … … 13 13 // Update Count : 119 14 14 // 15 16 #include "Eval.h" 15 17 16 18 #include <utility> // for pair -
src/Common/ResolvProtoDump.cpp
r34b4268 r24d6572 19 19 #include <iostream> 20 20 #include <set> 21 #include <sstream> 21 22 #include <unordered_set> 22 23 … … 26 27 #include "AST/Type.hpp" 27 28 #include "CodeGen/OperatorTable.h" 28 #include "Common/utility.h"29 29 30 30 namespace { -
src/Common/ScopedMap.h
r34b4268 r24d6572 37 37 template<typename N> 38 38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 41 Scope(const Scope &) = default; … … 46 46 typedef std::vector< Scope > ScopeList; 47 47 48 ScopeList scopes; ///< scoped list of maps 48 /// Scoped list of maps. 49 ScopeList scopes; 49 50 public: 50 51 typedef typename MapType::key_type key_type; … … 58 59 typedef typename MapType::const_pointer const_pointer; 59 60 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; 214 64 215 65 /// Starts a new scope … … 297 147 } 298 148 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 306 149 template< typename value_t > 307 150 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } … … 324 167 } 325 168 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; 331 176 } 332 177 … … 343 188 return c; 344 189 } 190 191 bool contains( const Key & key ) const { 192 return find( key ) != cend(); 193 } 194 }; 195 196 template<typename Key, typename Value, typename Note> 197 class 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) {} 224 public: 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 267 private: 268 scope_list *scopes; 269 wrapped_iterator it; 270 size_type level; 271 }; 272 273 template<typename Key, typename Value, typename Note> 274 class 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) {} 301 public: 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 348 private: 349 scope_list const *scopes; 350 wrapped_const_iterator it; 351 size_type level; 345 352 }; 346 353 -
src/Common/SemanticError.h
r34b4268 r24d6572 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 4 14:08:26 202213 // Update Count : 3 512 // Last Modified On : Sat Feb 25 12:01:31 2023 13 // Update Count : 37 14 14 // 15 15 … … 54 54 55 55 constexpr 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" }, 64 65 }; 65 66 … … 73 74 GccAttributes, 74 75 CppCopy, 76 DeprecTraitSyntax, 75 77 NUMBER_OF_WARNINGS, // This MUST be the last warning 76 78 }; -
src/Common/module.mk
r34b4268 r24d6572 20 20 Common/CodeLocationTools.hpp \ 21 21 Common/CodeLocationTools.cpp \ 22 Common/CompilerError.h \23 Common/Debug.h \24 22 Common/DeclStats.hpp \ 25 23 Common/DeclStats.cpp \ 26 24 Common/ErrorObjects.h \ 27 25 Common/Eval.cc \ 26 Common/Eval.h \ 28 27 Common/Examine.cc \ 29 28 Common/Examine.h \ … … 31 30 Common/Indenter.h \ 32 31 Common/Indenter.cc \ 32 Common/Iterate.hpp \ 33 33 Common/PassVisitor.cc \ 34 34 Common/PassVisitor.h \ … … 52 52 Common/Stats/Time.cc \ 53 53 Common/Stats/Time.h \ 54 Common/ UnimplementedError.h\54 Common/ToString.hpp \ 55 55 Common/UniqueName.cc \ 56 56 Common/UniqueName.h \ -
src/Common/utility.h
r34b4268 r24d6572 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // utility.h -- 7 // utility.h -- General utilities used across the compiler. 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Apr 25 14:26:00 202213 // Update Count : 5 112 // Last Modified On : Fri Feb 17 15:25:00 2023 13 // Update Count : 53 14 14 // 15 15 … … 19 19 #include <cctype> 20 20 #include <algorithm> 21 #include <functional>22 21 #include <iostream> 23 #include <iterator>24 22 #include <list> 25 23 #include <memory> 26 #include <sstream>27 24 #include <string> 28 25 #include <type_traits> 29 #include <utility>30 26 #include <vector> 31 27 #include <cstring> // memcmp … … 49 45 return 0; 50 46 } // 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 } // if61 }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;74 47 } 75 48 … … 168 141 splice( src, dst ); 169 142 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 list193 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 element206 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 );210 143 } 211 144 … … 236 169 } 237 170 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 amount250 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 273 171 // determines if pref is a prefix of str 274 172 static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) { 275 173 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 } 302 176 303 177 // ----------------------------------------------------------------------------- … … 356 230 ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } } 357 231 }; 358 359 // -----------------------------------------------------------------------------360 // Helper struct and function to support361 // for ( val : reverseIterate( container ) ) {}362 // syntax to have a for each that iterates backwards363 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 can470 // 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 support535 // for ( val : lazy_map( container1, f ) ) {}536 // syntax to have a for each that iterates a container, mapping each element by applying f537 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 }564 232 565 233 // ----------------------------------------------------------------------------- … … 583 251 } // ilog2 584 252 585 // -----------------------------------------------------------------------------586 /// evaluates expr as a long long int. If second is false, expr could not be evaluated587 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 the597 /// 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 position607 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 position611 ++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::less624 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 629 253 // Local Variables: // 630 254 // tab-width: 4 //
Note:
See TracChangeset
for help on using the changeset viewer.