source: src/Common/utility.h @ 60380a1

ADTast-experimental
Last change on this file since 60380a1 was c94b1f0, checked in by Andrew Beach <ajbeach@…>, 19 months ago

Removed unused (debug only?) code. If you want to change how GenStructMemberCalls? handles errors you may just need to write a local helper.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// utility.h -- General utilities used across the compiler.
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Fri Feb 17 15:25:00 2023
13// Update Count     : 53
14//
15
16#pragma once
17
18#include <cassert>
19#include <cctype>
20#include <algorithm>
21#include <iostream>
22#include <list>
23#include <memory>
24#include <sstream>
25#include <string>
26#include <type_traits>
27#include <vector>
28#include <cstring>                                                                              // memcmp
29
30#include "Common/Indenter.h"
31
32class Expression;
33
34/// bring std::move into global scope
35using std::move;
36
37/// partner to move that copies any copyable type
38template<typename T>
39T copy( const T & x ) { return x; }
40
41template< typename T >
42static inline T * maybeClone( const T *orig ) {
43        if ( orig ) {
44                return orig->clone();
45        } else {
46                return 0;
47        } // if
48}
49
50template< typename Input_iterator >
51void printEnums( Input_iterator begin, Input_iterator end, const char * const *name_array, std::ostream &os ) {
52        for ( Input_iterator i = begin; i != end; ++i ) {
53                os << name_array[ *i ] << ' ';
54        } // for
55}
56
57template< typename Container >
58void deleteAll( const Container &container ) {
59        for ( const auto &i : container ) {
60                delete i;
61        } // for
62}
63
64template< typename Container >
65void printAll( const Container &container, std::ostream &os, Indenter indent = {} ) {
66        for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) {
67                if ( *i ) {
68                        os << indent;
69                        (*i)->print( os, indent );
70                        // need an endl after each element because it's not easy to know when each individual item should end
71                        os << std::endl;
72                } // if
73        } // for
74}
75
76template< typename SrcContainer, typename DestContainer >
77void cloneAll( const SrcContainer &src, DestContainer &dest ) {
78        typename SrcContainer::const_iterator in = src.begin();
79        std::back_insert_iterator< DestContainer > out( dest );
80        while ( in != src.end() ) {
81                *out++ = (*in++)->clone();
82        } // while
83}
84
85template< typename SrcContainer, typename DestContainer, typename Predicate >
86void cloneAll_if( const SrcContainer &src, DestContainer &dest, Predicate pred ) {
87        std::back_insert_iterator< DestContainer > out( dest );
88        for ( auto x : src ) {
89                if ( pred(x) ) {
90                        *out++ = x->clone();
91                }
92        } // while
93}
94
95template< typename Container >
96void assertAll( const Container &container ) {
97        int count = 0;
98        for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) {
99                if ( !(*i) ) {
100                        std::cerr << count << " is null" << std::endl;
101                } // if
102        } // for
103}
104
105template < typename T >
106std::list<T> tail( std::list<T> l ) {
107        if ( ! l.empty() ) {
108                std::list<T> ret(++(l.begin()), l.end());
109                return ret;
110        } // if
111}
112
113template < typename T >
114std::list<T> flatten( std::list < std::list<T> > l) {
115        typedef std::list <T> Ts;
116
117        Ts ret;
118
119        switch ( l.size() ) {
120          case 0:
121                return ret;
122          case 1:
123                return l.front();
124          default:
125                ret = flatten(tail(l));
126                ret.insert(ret.begin(), l.front().begin(), l.front().end());
127                return ret;
128        } // switch
129}
130
131/// Splice src onto the end of dst, clearing src
132template< typename T >
133void splice( std::vector< T > & dst, std::vector< T > & src ) {
134        dst.reserve( dst.size() + src.size() );
135        for ( T & x : src ) { dst.emplace_back( std::move( x ) ); }
136        src.clear();
137}
138
139/// Splice src onto the begining of dst, clearing src
140template< typename T >
141void spliceBegin( std::vector< T > & dst, std::vector< T > & src ) {
142        splice( src, dst );
143        dst.swap( src );
144}
145
146template < typename T >
147void toString_single( std::ostream & os, const T & value ) {
148        os << value;
149}
150
151template < typename T, typename... Params >
152void toString_single( std::ostream & os, const T & value, const Params & ... params ) {
153        os << value;
154        toString_single( os, params ... );
155}
156
157template < typename ... Params >
158std::string toString( const Params & ... params ) {
159        std::ostringstream os;
160        toString_single( os, params... );
161        return os.str();
162}
163
164#define toCString( ... ) toString( __VA_ARGS__ ).c_str()
165
166template< typename... Args >
167auto filter(Args&&... args) -> decltype(std::copy_if(std::forward<Args>(args)...)) {
168  return std::copy_if(std::forward<Args>(args)...);
169}
170
171template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args >
172void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) {
173        auto i = begin( container );
174        while ( i != end( container ) ) {
175                auto it = next( i );
176                if ( pred( *i ) ) {
177                        if ( doDelete ) {
178                                delete *i;
179                        } // if
180                        container.erase( i );
181                } // if
182                i = it;
183        } // while
184}
185
186template<typename Container, typename Pred>
187void erase_if( Container & cont, Pred && pred ) {
188        auto keep_end = std::remove_if( cont.begin(), cont.end(), pred );
189        cont.erase( keep_end, cont.end() );
190}
191
192// determines if pref is a prefix of str
193static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) {
194        if ( pref.size() > str.size() ) return false;
195        return pref == str.substr(start, pref.size());
196}
197
198// -----------------------------------------------------------------------------
199// RAII object to regulate "save and restore" behaviour, e.g.
200// void Foo::bar() {
201//   ValueGuard<int> guard(var); // var is a member of type Foo
202//   var = ...;
203// } // var's original value is restored
204template< typename T >
205struct ValueGuard {
206        T old;
207        T& ref;
208
209        ValueGuard(T& inRef) : old(inRef), ref(inRef) {}
210        ~ValueGuard() { ref = old; }
211};
212
213template< typename T >
214struct ValueGuardPtr {
215        T old;
216        T* ref;
217
218        ValueGuardPtr(T * inRef) : old( inRef ? *inRef : T() ), ref(inRef) {}
219        ValueGuardPtr(const ValueGuardPtr& other) = delete;
220        ValueGuardPtr(ValueGuardPtr&& other) : old(other.old), ref(other.ref) { other.ref = nullptr; }
221        ~ValueGuardPtr() { if( ref ) *ref = old; }
222};
223
224template< typename aT >
225struct FuncGuard {
226        aT m_after;
227
228        template< typename bT >
229        FuncGuard( bT before, aT after ) : m_after( after ) {
230                before();
231        }
232
233        ~FuncGuard() {
234                m_after();
235        }
236};
237
238template< typename bT, typename aT >
239FuncGuard<aT> makeFuncGuard( bT && before, aT && after ) {
240        return FuncGuard<aT>( std::forward<bT>(before), std::forward<aT>(after) );
241}
242
243template< typename T >
244struct ValueGuardPtr< std::list< T > > {
245        std::list< T > old;
246        std::list< T >* ref;
247
248        ValueGuardPtr( std::list< T > * inRef) : old(), ref(inRef) {
249                if( ref ) { swap( *ref, old ); }
250        }
251        ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } }
252};
253
254// -----------------------------------------------------------------------------
255// O(1) polymorphic integer ilog2, using clz, which returns the number of leading 0-bits, starting at the most
256// significant bit (single instruction on x86)
257
258template<typename T>
259inline
260#if defined(__GNUC__) && __GNUC__ > 4
261constexpr
262#endif
263T ilog2(const T & t) {
264        if(std::is_integral<T>::value) {
265                const constexpr int r = sizeof(t) * __CHAR_BIT__ - 1;
266                if( sizeof(T) == sizeof(unsigned       int) ) return r - __builtin_clz  ( t );
267                if( sizeof(T) == sizeof(unsigned      long) ) return r - __builtin_clzl ( t );
268                if( sizeof(T) == sizeof(unsigned long long) ) return r - __builtin_clzll( t );
269        }
270        assert(false);
271        return -1;
272} // ilog2
273
274// Local Variables: //
275// tab-width: 4 //
276// mode: c++ //
277// compile-command: "make install" //
278// End: //
Note: See TracBrowser for help on using the repository browser.