├── .old └── u-field ├── Makefile ├── README.asciidoc ├── allocator.h ├── awk.h ├── b-field.sh ├── cj.h ├── cpp_logo.png ├── example_config ├── fld.h ├── hasher.h ├── index.txt ├── loops_macro.h ├── main.cc ├── matrix.h ├── note ├── scc ├── scc.h ├── simple ├── simple.h ├── u-all ├── u-awk ├── u-cj ├── u-hasher ├── u-matrix ├── u-scc ├── u-sed └── u-strr /.old/u-field: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | # CTORs 4 | scc 'str s("abc"); new_field f(s); f' 5 | scc 'new_field f("abc"); f' 6 | scc 'new_field f("abc"); new_field f2(f); f2' 7 | 8 | # Convertions explicit 9 | scc 'field s("1.23"); (double)s' 10 | scc 'field s("1.23"); (float)s' 11 | scc 'field s("1.23"); (int)s' 12 | scc 'field s("1.23"); (long)s' 13 | scc 'field s("1.23"); (int)s' 14 | 15 | # Convertions operators 16 | scc 'field s("1.11"); s=1' 17 | scc 'field s("1.11"); s=1l' 18 | scc 'field s("1.11"); s=1.f' 19 | 20 | scc 'field s("1.11"); s+1' 21 | scc 'field s("1.11"); s+1l' 22 | 23 | scc 'field s("1.11"); s+1' 24 | scc 'field s("1.11"); s=1.1' 25 | scc 'field s("1.11"); s=1.1' 26 | scc 'field s("1.11"); s+1.1' 27 | scc 'field s("1.11"); s+2.22' 28 | scc 'field s("1.11"); s+=2.22' 29 | scc 'field s("1.11"); s=2.22' 30 | scc 'field s("1.11"); s=1+2.22' 31 | scc 'field s("1.11"); s+1.11' 32 | 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################################### make + install 3 | make: 4 | @echo "SCC is headers only code, no preliminary compilation is needed." 5 | @echo "After checking out from repo, it's in read-to-use state." 6 | 7 | PREFIX=/usr/local 8 | install: 9 | @echo "not implemented - just use this (scc/) directory." 10 | # mkdir -p ${PREFIX}/bin/ 11 | # cp -v scc ${PREFIX}/bin/ 12 | # mkdir -p ${PREFIX}/include/scc/ 13 | # cp -v *.h ${PREFIX}/include/scc/ 14 | 15 | 16 | ############################################################################################### asciidoc gen 17 | ASCIIDOC_FILTERS ?= /usr/share/asciidoc/filters 18 | 19 | 20 | ifeq ($(USER),lvv) 21 | HOMEDIR := /home/lvv/p/volnitsky.com/ 22 | INCLUDE := $(HOMEDIR)/include.mk 23 | else 24 | INCLUDE := /dev/null 25 | endif 26 | 27 | 28 | include $(INCLUDE) 29 | 30 | ##index.txt: 31 | # head -n-1 README.asciidoc > /tmp/t.ad 32 | 33 | index.html: /tmp/t.ad 34 | 35 | /tmp/t.ad: README.asciidoc 36 | head -n-1 README.asciidoc > /tmp/t.ad 37 | 38 | 39 | u-meta.cc: *.h 40 | 41 | #COPY_LIST += $(wildcard *.png) 42 | 43 | ########################################################### Precompiled Headers 44 | # http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html#manual.intro.using.headers.pre 45 | # TR http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html 46 | ALL_INC=$(wildcard /usr/lib64/gcc/x86_64-pc-linux-gnu/4.7.0-*/include/g++-v4/x86_64-pc-linux-gnu/bits/stdc++.h) 47 | 48 | 49 | #H = $(wildcard *.h) 50 | #GCH = $(H:.h=.h.gch) stdc++.h.gch 51 | GCH = scc.h.gch 52 | 53 | 54 | 55 | stdc++.h.gch: 56 | g++ -Winvalid-pch -std=gnu++11 -x c++-header -o $@ $(ALL_INC) 57 | 58 | %.h.gch: %.h 59 | g++ -Winvalid-pch -std=gnu++11 -I . -I .. -x c++-header -o $@ $< 60 | 61 | gch: ${GCH} 62 | echo: 63 | : H: ${H} 64 | : GCH: ${GCH} 65 | 66 | ########################################################### 67 | 68 | 69 | 70 | CLEAN_LIST += t-print t-regex t-meta 71 | 72 | #CXXFLAGS += -std=gnu++11 -Wall -I/home/lvv/p/ 73 | CXXFLAGS += -Wall -I/home/lvv/p/ -I .. 74 | 75 | t-buf-r: t-buf 76 | 77 | ######################################################## SCCPP 78 | 79 | u-sccpp: CXXFLAGS=-Wall -I/home/lvv/p/ -D_GLIBCXX_DEBUG 80 | sccpp: CXXFLAGS=-Wall -I/home/lvv/p/ -O3 81 | u-sccpp: u-sccpp.cc 82 | $(CXX) $(CXXFLAGS) $< -o $@ 83 | sccpp: sccpp.cc 84 | $(CXX) $(CXXFLAGS) $< -o $@ 85 | u-sccpp sccpp: sccpp.h 86 | 87 | ######################################################## BENCH 88 | BENCH_FILE=/tmp/bf 89 | 90 | bench_lines: $(BENCH_FILE) 91 | #sh -c "[ -x /tmp/x ] && mv /tmp/x{,.old}" 92 | scc -O -x /tmp/x -n 'WRl n++; n' 93 | cat $(BENCH_FILE) > /dev/null 94 | /usr/bin/time -f'\t%Es (%Us+%Ss) \t%MKB\n' /tmp/x < $(BENCH_FILE) 95 | 96 | bench: $(BENCH_FILE) 97 | cat $(BENCH_FILE) > /dev/null 98 | @echo 99 | LC_ALL=C time wc -wl $(BENCH_FILE) 100 | @echo 101 | LC_ALL=C time gawk '{n+=NF}; END{print n, NR}' $(BENCH_FILE) 102 | @echo 103 | LC_ALL=C time mawk '{n+=NF}; END{print n, NR}' $(BENCH_FILE) 104 | @echo 105 | scc -O -x /tmp/x -n 'WRl n+=NF; __ NR ^ n;' 106 | LC_ALL=C time /tmp/x < $(BENCH_FILE) 107 | 108 | 109 | $(BENCH_FILE): 110 | scc 'char C[]="123456789"; REP(5*1000*1000) { REP(10) _ C << " "; __ "";}' > $(BENCH_FILE) 111 | 112 | ###################################################### Unit Tests 113 | CXXFLAGS+= -std=gnu++11 -Wall -O0 -ggdb3 -D_GLIBCXX_DEBUG -fno-inline -I/home/lvv/p/ 114 | 115 | -------------------------------------------------------------------------------- /README.asciidoc: -------------------------------------------------------------------------------- 1 | // vim:set ft=asciidoc: 2 | SCC — Simple C++ 3 | =============== 4 | 5 | SCC is +++C++ +++ snippets evaluator at shell prompt 6 | 7 | 8 | See full docs at http://volnitsky.com/project/scc[] 9 | -------------------------------------------------------------------------------- /allocator.h: -------------------------------------------------------------------------------- 1 | // TR http://stackoverflow.com/questions/12556638/stl-container-constructors-allocator-parameter-and-scoped-allocators 2 | // TR sample allocator -- http://stackoverflow.com/questions/8089850/how-to-overwrite-the-default-behavor-of-the-construct-method-in-the-allocator-cl/8090161#8090161 3 | // TR http://www2.research.att.com/~bs/rg++0xFAQ.html#scoped-allocator 4 | // TR http://stackoverflow.com/questions/11373796/curom-memory-allocator-for-stl-map 5 | // TR http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4079/Allocators-STL.htm 6 | // TO TRY -- http://stackoverflow.com/questions/17548032/c11-memory-pool-class-workaround-for-static-casting-from-void 7 | 8 | /* (from c++ now presentation) - A Minimal Allocator • Much of the rg++03 boilerplate is now defaulted 9 | 10 | template 11 | class MyAlloc { 12 | public: 13 | typedef T value_type; 14 | MyAlloc(); 15 | template 16 | MyAlloc(const MyAlloc&); 17 | T* allocate(std::size_t); 18 | void deallocate(T*, std::size_t); 19 | }; 20 | template bool operator==(const MyAlloc&, const MyAlloc&); 21 | template bool operator!=(const MyAlloc&, const MyAlloc&); 22 | */ 23 | 24 | #ifndef LVV_ALLOCATOR_H 25 | #define LVV_ALLOCATOR_H 26 | 27 | #include 28 | #include 29 | using std::cout; 30 | using std::endl; 31 | using std::flush; 32 | 33 | template // TRACE ALLOCATOR 34 | struct trace_allocator : std::allocator { 35 | 36 | typename std::allocator::pointer 37 | allocate(typename std::allocator::size_type n, typename std::allocator::const_pointer = 0) { 38 | cout << "\tAllocating: " << n << " itens." << endl << flush; 39 | return reinterpret_cast::pointer>(::operator new(n * sizeof (T))); 40 | } 41 | 42 | trace_allocator() {}; 43 | template trace_allocator( const trace_allocator& _Right ) {}; // conversion CTOR needed for gg++ 44 | 45 | void 46 | deallocate(typename std::allocator::pointer p, typename std::allocator::size_type n) { 47 | cout << "\tDealloc: " << n << " itens." << endl << flush; 48 | ::operator delete(p); 49 | } 50 | 51 | template struct rebind { typedef trace_allocator other; }; 52 | 53 | 54 | }; 55 | 56 | 57 | template // NO-DELETE ALLOCATOR 58 | struct nd_allocator : std::allocator { 59 | static const size_t capacity = 200*1000*1000; 60 | static char *data; 61 | static char *b; // free begin 62 | static char *e; // end of data buffer; 63 | static int ref_cnt; 64 | nd_allocator() : std::allocator() { 65 | if(!ref_cnt) { 66 | data = new char[capacity]; 67 | b = data; 68 | e = data + capacity; 69 | }; 70 | ++ref_cnt; 71 | } 72 | 73 | template 74 | nd_allocator(const nd_allocator& other) { ref_cnt++; }; 75 | 76 | ~nd_allocator() { --ref_cnt; if (!ref_cnt) delete [] data; }; 77 | 78 | typename std::allocator::pointer 79 | allocate(typename std::allocator::size_type n, typename std::allocator::const_pointer = 0) { 80 | //__ "\t nd: +" << n << " x " << sizeof(T); 81 | auto ret = reinterpret_cast ::pointer> (b); 82 | b += n * sizeof (T); 83 | if (b>e) throw (std::bad_alloc()); 84 | return ret; 85 | } 86 | 87 | void 88 | deallocate(typename std::allocator::pointer p, typename std::allocator::size_type n) { 89 | //::operator delete(p); 90 | //assert (false); 91 | //__ "\t nd: -" << n; 92 | } 93 | 94 | template struct rebind { typedef nd_allocator other; }; 95 | }; 96 | 97 | template char* nd_allocator::data = nullptr; 98 | template char* nd_allocator::b = nullptr; 99 | template char* nd_allocator::e = nullptr; 100 | template int nd_allocator::ref_cnt = 0; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /awk.h: -------------------------------------------------------------------------------- 1 | // Record, AWK vars, buf_t 2 | 3 | #ifndef SCC_AWK_H 4 | #define SCC_AWK_H 5 | 6 | #include 7 | 8 | /////////////////////////////////////////////////////////////////////////////// R_t 9 | 10 | template 11 | struct R_t : std::vector { 12 | 13 | T& operator()(size_t I) { 14 | if (I==0) return a; 15 | if (this->size()resize(I); // reference to non existant field 16 | return (*this)[I-1]; 17 | }; 18 | 19 | T& operator()(const char* s) { 20 | auto it = header.find(s); 21 | if (it == header.end()) { 22 | cerr << "scc error: header \"" << s << "\" not found\n"; 23 | return (*this)[0]; 24 | } else { 25 | return (*this)[it->second]; 26 | } 27 | }; 28 | 29 | T a; // All_of record 30 | map header; 31 | 32 | }; 33 | 34 | R_t F; 35 | 36 | /////////////////////////////////////////////////////////////////////////////// AWK's vars 37 | 38 | #define $0 F.a 39 | #define $1 F(1) 40 | #define $2 F(2) 41 | #define $3 F(3) 42 | #define $4 F(4) 43 | #define $5 F(5) 44 | #define $6 F(6) 45 | #define $7 F(7) 46 | #define $8 F(8) 47 | #define $9 F(9) 48 | #define $10 F(10) 49 | #define $11 F(11) 50 | #define $12 F(12) 51 | #define $13 F(13) 52 | #define $14 F(14) 53 | #define $15 F(15) 54 | #define $16 F(16) 55 | #define $17 F(17) 56 | #define $18 F(18) 57 | #define $19 F(19) 58 | #define $20 F(20) 59 | 60 | #define $NF F(NF) 61 | #define $ F 62 | 63 | long NF = 0; 64 | long FNR = 0; 65 | long NR = 0; 66 | 67 | //string __attribute__((unused)) line; 68 | 69 | 70 | const char* __attribute__((unused)) CSV="\"((?:(?:\\\\\")|[^\"])*)\"(\\s*,\\s*|$)"; 71 | 72 | /* 73 | #ifdef scc_IFS 74 | string __attribute__((unused)) FS(scc_IFS); 75 | #else 76 | #ifdef scc_ifs 77 | string __attribute__((unused)) FS("([^" scc_ifs "]+)(" scc_ifs "|$)"); // field (data) is 1st group; FS is second group 78 | #else 79 | string __attribute__((unused)) FS("(\\S+)(\\s+|$)"); // field (data) is 1st group; FS is second group 80 | #endif 81 | #endif 82 | */ 83 | 84 | strr ORS; 85 | strr RS; 86 | 87 | strr OFS 88 | #ifdef scc_OFS 89 | (scc_OFS); 90 | #else 91 | (" "); 92 | #endif 93 | 94 | strr FS 95 | #ifdef scc_ifs 96 | (scc_ifs); 97 | #else 98 | (" "); 99 | #endif 100 | 101 | strr PAD 102 | #ifdef scc_PAD 103 | (scc_PAD); 104 | #else 105 | (" \t"); 106 | #endif 107 | 108 | char PAD_tab[256] = {0}; 109 | 110 | /////////////////////////////////////////////////////////////////////////////// Utils functions 111 | 112 | 113 | 114 | /////////////////////////////////////////////////////////////////////////////// INPUT BUF 115 | 116 | static const char * FILENAME = 0; 117 | 118 | struct buf_t { 119 | const static size_t buf_size=1000000; 120 | bool good_file; // !eof 121 | char bob[buf_size+1];// buffer dimentions 122 | const char *eob; // end of buffer 123 | const char *bod, *eod; // data in buffer 124 | const char *path; 125 | int fd; // file 126 | char **&argv; 127 | char **argv_e; 128 | 129 | 130 | bool next_file() { 131 | if (fd==0 || argv==argv_e) { 132 | good_file = false; 133 | return false; 134 | } 135 | 136 | FILENAME = *argv++; 137 | if (fd > 0) close(fd); 138 | fd = open(FILENAME, O_RDONLY); 139 | if (fd < 0) { cerr << "scc error: can not open file \"" << FILENAME << "\"\n"; exit(1); } 140 | posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); 141 | FNR = 0; 142 | good_file = true; 143 | return true; 144 | } 145 | 146 | 147 | buf_t (char**&argv, char**argv_e) 148 | : good_file(true), fd(-1), argv(argv), argv_e(argv_e) 149 | { 150 | if (argv < argv_e) { 151 | next_file(); 152 | } else { 153 | FILENAME = "stdin"; 154 | fd = 0; 155 | } 156 | bod = eod = bob; 157 | eob = bob+buf_size; 158 | } 159 | 160 | size_t capacity () const{ return buf_size; } 161 | ssize_t size () const{ return eod-bod; } 162 | bool empty () const{ return size() <= 0; } 163 | void clear () { eod = bod = bob; } 164 | 165 | 166 | bool fill () { 167 | size_t buf_free_space = eob-eod; 168 | ssize_t got; 169 | if (buf_free_space > 0) { 170 | retry: 171 | got = read (fd, const_cast(eod), buf_free_space); 172 | if (got == -1 && errno == EINTR) goto retry; 173 | if (got <= 0) return false; 174 | eod += got; 175 | } 176 | return true; 177 | } 178 | 179 | ///////////////////////////////////////////////////////////////////////////////////////////////// GET_REC 180 | template 181 | bool get_rec (sep_T RS, sep_T FS, R_t& F) { 182 | 183 | try_next_file: 184 | if (!good_file && is_stream && !next_file() ) return false; 185 | if (!good_file && !is_stream ) return false; 186 | 187 | const char *p (bod); 188 | F.a.b = p; // record 189 | 190 | strr_allocator.clear(); 191 | #define FINISH_RECORD { parse_rec(F); NF = F.size(); bod = p; FNR++; NR++; } 192 | 193 | while(1) { // read until EOR 194 | size_t unused_data = eod - p; 195 | if (!unused_data) { 196 | size_t buf_free_space = eob-eod; 197 | 198 | if (!buf_free_space) { // relocate data to begining of buffer 199 | if (F.a.b == bob ) { 200 | cerr << "warning: Line is too big for buffer. Splitting line.\n"; 201 | FINISH_RECORD; 202 | return true; 203 | } 204 | 205 | ssize_t data_size = size(); 206 | assert(eob-bob > 2*data_size); // FIXME: replace assert with realloc 207 | 208 | memcpy(const_cast(bob), const_cast(bod), data_size); 209 | bod = F.a.b = bob; 210 | eod = p = bob + data_size; 211 | } 212 | 213 | if ( !(good_file = fill()) ) { // EOF 214 | if ( F.a.b == p ) goto try_next_file; // if EOF at BoR --> try next file 215 | F.a.e = p; 216 | FINISH_RECORD; 217 | return true; 218 | } 219 | } 220 | 221 | p = F.a.e = search (p, eod, RS.b, RS.e); 222 | if (p != eod) { 223 | p += RS.size(); 224 | FINISH_RECORD; 225 | return true; 226 | } 227 | } 228 | 229 | FINISH_RECORD; 230 | return true; 231 | } 232 | 233 | private: 234 | 235 | void parse_rec (R_t& F) { 236 | F.clear(); 237 | if (F.a.empty()) return; 238 | const char *sep, *eof; 239 | const char *bof = F.a.b; 240 | 241 | // TODO: gawk: In the special case that FS is a single space, fields are separated by runs of spaces 242 | // and/or tabs and/or newlines. (But see the section POSIX COMPATIBILITY, below). 243 | 244 | do { 245 | while( bof < F.a.e && PAD_tab[size_t(*bof)] ) bof++; // skip padding 246 | sep = eof = search(bof, F.a.e, FS.b, FS.e); // 247 | while( bof < (eof-1) && PAD_tab[size_t(*(eof-1))] ) eof--; // eat padding begore FS 248 | F.push_back(fld(bof,eof)); 249 | bof = sep + FS.size(); 250 | } while (bof < F.a.e); 251 | } 252 | 253 | }; 254 | 255 | #endif // SCC_AWK 256 | -------------------------------------------------------------------------------- /b-field.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim:set ts=4 sw=4 syntax=sh: 3 | 4 | 5 | N=1000000 6 | 7 | # generate input file (N records, 10 fields) 8 | 9 | if [ ! -f b-field.in ] ; then 10 | scc 'for(; l<'$N'; l++) { for(i=1;i<=10; i++) _ l*10+i," "; _ l, "\t"; }' > b-field.in 11 | else 12 | cat b-field.in > /dev/null 13 | fi 14 | 15 | # sup-up 10th field 16 | 17 | # string-field 18 | rm -f /tmp/sf 19 | CXXFLAGS='-O3' scc -x /tmp/sf 'WRL n+=F10; n' 20 | echo -n "scc: "; command time -f %U /tmp/sf < b-field.in 21 | echo -n "scc: "; command time -f %U /tmp/sf < b-field.in 22 | echo -n "scc: "; command time -f %U /tmp/sf < b-field.in 23 | echo -n "scc: "; command time -f %U /tmp/sf < b-field.in 24 | echo -n "scc: "; command time -f %U /tmp/sf < b-field.in 25 | echo -n "gawk: "; command time -f %U gawk '{s+=$10} END{print s}' < b-field.in 26 | echo -n "mawk: "; command time -f %U mawk '{s+=$10} END{print s}' < b-field.in 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /cj.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LVV_CODEJAM_H 3 | #define LVV_CODEJAM_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | //#ifndef LVV_MATRIX_H 12 | //#include "scc/matrix.h" 13 | //#endif 14 | 15 | ///////////////////////////////////////////////////////////////////// UTILS 16 | 17 | 18 | 19 | /* 20 | template 21 | T gcd(T a, T b) { 22 | if (a < 0) a = -a; 23 | if (b < 0) b = -b; 24 | if (a == 0) return b; 25 | if (a > b) return gcd(b, a); 26 | return gcd(b % a, a); 27 | } 28 | */ 29 | // to check http://stackoverflow.com/questions/110344/algorithm-to-calculate-the-number-of-divisors-of-a-given-number 30 | // 31 | 32 | 33 | ////// HISTOGRAM 34 | 35 | template 36 | std::vector 37 | histogram_vector(Rg const& rg) { 38 | std::vector result(std::numeric_limits::max() - std::numeric_limits::min()); 39 | for(const auto& el : rg) ++result[el - std::numeric_limits::min()]; 40 | return result; 41 | } 42 | 43 | template 44 | std::map 45 | histogram(Rg const& rg) { 46 | std::map result; 47 | for(const auto& el : rg) ++result[el]; 48 | return result; 49 | } 50 | 51 | 52 | #define countof(array) (sizeof (array) / sizeof(array[0])) 53 | 54 | 55 | #define scc_RO 1 56 | #include // http://github.com/lvv/ro 57 | #include // http://github.com/lvv/scc 58 | 59 | #endif // LVV_CODEJAM_H 60 | -------------------------------------------------------------------------------- /cpp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvv/scc/5feb32fdfa6fae786dab4459485ba09abfec44af/cpp_logo.png -------------------------------------------------------------------------------- /example_config: -------------------------------------------------------------------------------- 1 | 2 | ### EXAMPLE CONFIG FOR SCC 3 | ### 4 | ### copy (and edit) this file to any of: /etc/scc, ~/.scc, .scc 5 | ### 6 | ### lines with single '#' are default values 7 | ### lines with double '##' are examples 8 | ### 9 | ### NOTE: this is bash syntax - no spaces around "=" 10 | ### 11 | 12 | 13 | ### RO ########################## 14 | # unset scc_RO 15 | ## scc_RO=1 16 | 17 | 18 | ### AWK ########################## 19 | # unset scc_AWK 20 | ## scc_AWK=1 21 | 22 | ### CXX ########################## 23 | # default_CXX=g++ 24 | ## default_CXX=g++-4.5.4 25 | ## default_CXX=g++-4.7.2 CXXFLAGS+=" -std=gnu++11 " 26 | ## default_CXX=clang CXXFLAGS+=" -std=gnu++11 -D__STRICT_ANSI__ " 27 | 28 | 29 | # CXXFLAGS+=" -Wall -pipe -Wno-unused-function " 30 | 31 | ### these are added CXXFLAGS if option `-O` or `-g` is set 32 | # O_FLAGS=" -O3 -march=native" 33 | # g_FLAGS=" -O0 -ggdb -D_GLIBCXX_DEBUG " 34 | 35 | # vim:ft=sh 36 | -------------------------------------------------------------------------------- /fld.h: -------------------------------------------------------------------------------- 1 | // strr, fld type 2 | 3 | #ifndef SCC_FLD_H 4 | #define SCC_FLD_H 5 | 6 | struct strr { /////////////////////////////////////////////////////// STRR 7 | const char *b, *e; 8 | 9 | // CTOR 10 | strr() : b(0), e(0) {}; 11 | strr(const char* s) : b(s) { e = b; while(*++e); }; 12 | strr(const char* b, const char* e): b(b), e(e) {}; 13 | 14 | // MEMBERS 15 | size_t size() const { return e-b; }; 16 | size_t empty() const { return e-b == 0; }; 17 | bool operator==(strr sr) const { return std::equal(b, e, sr.b); }; 18 | 19 | typedef const char* iterator; 20 | typedef const char* const const_iterator; 21 | iterator begin() const { return b; }; 22 | iterator end() const { return e; }; 23 | }; 24 | 25 | 26 | #ifdef scc_RO 27 | //namespace { 28 | namespace ro { 29 | template<> struct is_ioable_t : std::true_type {}; 30 | template<> struct is_range_t : std::false_type {}; 31 | }; 32 | //}; 33 | #endif 34 | 35 | std::ostream& 36 | operator<< (std::ostream& os, const strr& sr) { 37 | os.write(sr.b, sr.size()); 38 | return os; 39 | }; 40 | 41 | 42 | 43 | struct strr_allocator_t { 44 | const static size_t size = 10000; 45 | char *spool_begin; 46 | char *spool_end; 47 | char *data_end; 48 | strr_allocator_t() : spool_begin(new char[size]), spool_end(spool_begin+size) { clear(); }; 49 | ~strr_allocator_t() { delete spool_begin;}; 50 | void clear() { data_end = spool_begin; } 51 | 52 | char* allocate(size_t sz) { 53 | char *p = data_end; 54 | data_end += sz; 55 | assert(data_end <= spool_end); 56 | return p; 57 | } 58 | }; 59 | 60 | 61 | static strr_allocator_t strr_allocator; 62 | 63 | 64 | struct fld : strr { 65 | 66 | fld() : strr() {}; 67 | fld(const char* b, const char* e) : strr(b, e) {}; 68 | // FIXME -- DTOR 69 | 70 | 71 | // CONVERT FROM T 72 | explicit fld(const char* s) : strr(s) {}; 73 | template fld(const char (&s)[N]) : strr(s) {}; 74 | explicit fld(const std::string& s) { assign (s.begin(), s.end()); }; 75 | explicit fld(int i) {*this = (long)i;}; 76 | explicit fld(long i) {*this = (long)i;}; 77 | explicit fld(double i) {*this = (double)i;}; 78 | 79 | // CONVERT TO T 80 | template T convert_to() const { std::istringstream is; T x; is.str(std::string(this->b, this->e)); is >> x; return x; } 81 | 82 | template explicit operator T() const { return convert_to(); } 83 | /* non-explicit, default */ operator double() const { return convert_to(); } 84 | 85 | operator std::string() const { return string(this->b, this->e); } 86 | 87 | 88 | 89 | // CONVERT TO INTEGRAL 90 | template 91 | T TO_TEST_to_integral() const { 92 | T sign = 1; 93 | T base = 10; 94 | const char *p = b; 95 | 96 | for (; p 116 | fld& 117 | assign(IT b_, IT e_) { 118 | size_t size = e_-b_; 119 | b = strr_allocator.allocate(size); 120 | e = b + size; 121 | std::copy (b_, e_, const_cast(b)); 122 | return *this; 123 | } 124 | 125 | // op= 126 | fld& operator= (const fld& x) { assign(x.b, x.e); return *this; } 127 | 128 | template fld& operator= (const char (&S)[N]) { *this = fld(S); return *this; } 129 | template fld& operator= (const T& x) { ostringstream os; os << x; string s = os.str(); assign(s.begin(), s.end()); return *this; } 130 | 131 | // op+= 132 | template fld& operator+= (T x) { return *this = T(*this) + x; } 133 | fld& operator+= (const fld& s2) { return *this = double(*this) + double(s2); } 134 | // op-= 135 | template fld& operator-= (T x) { return *this = T(*this) - x; } 136 | fld& operator-= (const fld& s2) { return *this = double(*this) - double(s2); } 137 | // op*= 138 | template fld& operator*= (T x) { return *this = T(*this) * x; } 139 | fld& operator*= (const fld& s2) { return *this = double(*this) * double(s2); } 140 | // op/= 141 | template fld& operator/= (T x) { return *this = T(*this) / x; } 142 | fld& operator/= (const fld& s2) { return *this = double(*this) / double(s2); } 143 | }; 144 | 145 | 146 | // op+ 147 | template T operator+ (const fld& sr, T x) { return T(sr) + x; } 148 | template T operator+ (T x, const fld& sr) { return T(sr) + x; } 149 | double operator+ (const fld& s1, const fld& s2){ return double(s1) + double(s2); } 150 | 151 | // op- 152 | template T operator- (const fld& sr, T x) { return T(sr) - x; } 153 | template T operator- (T x, const fld& sr) { return T(sr) - x; } 154 | double operator- (const fld& s1, const fld& s2){ return double(s1) - double(s2); } 155 | 156 | // op* 157 | //template T operator* (const fld& sr, T x) { return T(sr) * x; } 158 | template T operator* (T x, const fld& sr) { return T(sr) * x; } 159 | double operator* (const fld& s1, const fld& s2){ return double(s1) * double(s2); } 160 | 161 | // op/ 162 | template T operator/ (const fld& sr, T x) { return T(sr) / x; } 163 | template T operator/ (T x, const fld& sr) { return x / T(sr); } 164 | double operator/ (const fld& s1, const fld& s2){ return double(s1) / double(s2); } 165 | 166 | // op% 167 | template T operator% (const fld& sr, T x) { return T(sr) % x; } 168 | template T operator% (T x, const fld& sr) { return T(sr) % x; } 169 | long operator% (const fld& s1, const fld& s2){ return long(s1) * long(s2); } 170 | 171 | 172 | // traits 173 | #ifdef scc_RO 174 | //namespace { 175 | namespace ro { 176 | template<> struct is_ioable_t : std::true_type {}; 177 | template<> struct is_range_t : std::false_type {}; 178 | 179 | template<> struct is_string_t : std::true_type {}; // so that strr acceptable to regex expressions 180 | template<> struct is_string_t : std::true_type {}; // so that strr acceptable to regex expressions 181 | }; 182 | //}; 183 | #endif 184 | 185 | #endif // SCC_AWK 186 | -------------------------------------------------------------------------------- /hasher.h: -------------------------------------------------------------------------------- 1 | #ifndef SCC_HASHER_H 2 | #define SCC_HASHER_H 3 | 4 | #include 5 | /////////////////// TUPLE 6 | // from http://stackoverflow.com/questions/7110301/generic-hash-for-tuples-in-unordered-map-unordered-set 7 | namespace std{ 8 | namespace { 9 | 10 | // Code from boost 11 | // Reciprocal of the golden ratio helps spread entropy 12 | // and handles duplicates. 13 | // See Mike Seymour in magic-numbers-in-boosthash-combine: 14 | // http://stackoverflow.com/questions/4948780 15 | 16 | template 17 | inline void hash_combine(std::size_t& seed, T const& v) { 18 | seed ^= hash()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); 19 | } 20 | 21 | // Recursive template code derived from Matthieu M. 22 | template ::value - 1> 23 | struct HashValueImpl { 24 | static void apply(size_t& seed, Tuple const& tuple) { 25 | HashValueImpl::apply(seed, tuple); 26 | hash_combine(seed, get(tuple)); 27 | } 28 | }; 29 | 30 | template 31 | struct HashValueImpl { 32 | static void apply(size_t& seed, Tuple const& tuple) { 33 | std::hash_combine(seed, get<0>(tuple)); 34 | } 35 | }; 36 | } 37 | 38 | template 39 | struct hash> { 40 | size_t 41 | operator()(std::tuple const& tt) const { 42 | size_t seed = 0; 43 | HashValueImpl >::apply(seed, tt); 44 | return seed; 45 | } 46 | 47 | }; 48 | } 49 | 50 | /////////////////// PAIR 51 | 52 | namespace std { 53 | template 54 | struct hash> { 55 | size_t operator()(const pair& val ) const { 56 | return hash()(val.first) ^ hash()(val.second); 57 | } 58 | }; 59 | }; 60 | 61 | /////////////////// ARRAY 62 | 63 | #include 64 | 65 | namespace std { 66 | template 67 | struct hash > { 68 | typedef array argument_type; 69 | typedef size_t result_type; 70 | 71 | result_type operator()(const argument_type& a) const { 72 | hash hasher; 73 | result_type h = 0; 74 | for (result_type i = 0; i < N; ++i) { 75 | h = h * 31 + hasher(a[i]); 76 | } 77 | return h; 78 | } 79 | }; 80 | } 81 | #endif // SCC_HASHER_H 82 | -------------------------------------------------------------------------------- /index.txt: -------------------------------------------------------------------------------- 1 | include::/tmp/t.ad[] 2 | 3 | +++ +++ 4 | 5 | * Repo: httpx://github.com/lvv/scc[GitHub], httpx://bitbucket.org/lvv/scc[BitBucket] + 6 | * License: httpx://en.wikipedia.org/wiki/Boost_Software_License[Boost Software License] 7 | 8 | +++ +++ 9 | 10 | C++ REPL 11 | -------- 12 | 13 | At bash prompt - expression evaluated and printed: 14 | 15 | ---------------------------------------------------------------------------- 16 | scc 2+2 17 | 4 18 | ---------------------------------------------------------------------------- 19 | 20 | If expression is not terminated with semicolon, it is sent to `std::cout`. 21 | If snippet have bash special characters, it must be in single or double 22 | quotes. If expression starts with minus, end-of-options indicator `--` must be used: 23 | 24 | ---------------------------------------------------------------------------- 25 | scc '"hello world"' 26 | hello world 27 | 28 | scc -- -42 29 | -42 30 | 31 | scc "bitset\<8>('a')" 32 | 01100001 33 | 34 | scc 'double x=0.5; sin(x)' 35 | 0.479426 36 | 37 | echo "ABC" | scc 'char c; while (cin>>c) cout << tolower(c);' 38 | abc 39 | ---------------------------------------------------------------------------- 40 | 41 | If double semicolon `;;` is present, then what come before it is goes before `main` (into the file scope): 42 | 43 | -------------------------------------------- 44 | scc 'int f(int i) {return i+i;} ;; f(10)' 45 | 20 46 | -------------------------------------------- 47 | 48 | Snippet is evaluated in environment where most of +++C++ +++ Standard Library includes are included and 49 | most STD entities are imported into default namespace with `using std::...;` 50 | 51 | If you need only plain +++C++ +++ REPL, that is about all you need to know. 52 | You can skip to link:#_install[install] section now. SCC optional modules are described below. 53 | 54 | 55 | Shortcuts and predeclared vars 56 | ------------------------------- 57 | 58 | Shortcuts are typedefs and macros to cut verbosity for REPL 1-liner environment. 59 | 60 | ------------------------------------------------------ 61 | str --> std::string 62 | vint --> std::vector 63 | vfloat --> std::vector 64 | lint --> std::list 65 | dint --> std::deque 66 | WRL --> while(read_line()) 67 | ... 68 | ------------------------------------------------------ 69 | 70 | Some variables are pre-defined. 71 | You don't need to remember these. Predefined variables are defined in external 72 | to snippet scope, so you can re-define these to what ever you want. 73 | 74 | * `i`, `j`, `k`, `n`, `m` -- `long`, initialized to 0 75 | * `x`, `y`, `z` -- `double`, initialized to 0 76 | * `s`, `w` -- `std::string` 77 | * `c` -- `char` 78 | * `p` -- `char*` 79 | 80 | 81 | 82 | ///////////////////////////////////////////////////////////////////// 83 | Examples 84 | -------- 85 | 86 | Square an array. +++C++11 +++ is on by default: 87 | 88 | ---------------------------------------------------------------------------- 89 | scc 'vint V{1,2,3}; for(auto v:V) v*=v; V' 90 | {1, 4, 9} 91 | ---------------------------------------------------------------------------- 92 | */ 93 | 94 | Calculate words frequencies from `stdin`. (`w` - is pre-defined `std::string`) 95 | 96 | ---------------------------------------------------------------------------- 97 | echo aa bb aa | scc 'map M; while(cin>>w) M[w]++; M' 98 | {⟨aa,2⟩, ⟨bb,1⟩} 99 | ---------------------------------------------------------------------------- 100 | 101 | You can also find a lot of examples in `u-*` files. These are unit-test like files. 102 | ///////////////////////////////////////////////////////////////////// 103 | 104 | 105 | 106 | 107 | RO Module 108 | ---------- 109 | 110 | http://volnitsky.com/project/ro/[Range Operators] (headers only 111 | library) was recently split off SCC. It can be useful if you use STL 112 | containers, strings and want simpler replacement for `std::cout`. 113 | 114 | Some examples of what it can do: 115 | 116 | ----------------------------------------------------------------------------------------- 117 | 118 | // Can print ranges, container, tuples, etc directly (vint is vector) : 119 | scc 'vint V{1,2,3}; V' 120 | {1,2,3} 121 | 122 | // Assign 42 to 2..5 123 | scc 'vint V=range(0,9); range(V/2, V/5) = 42; V' 124 | {0, 1, 42, 42, 42, 5, 6, 7, 8, 9} 125 | 126 | // Find (brute force algorithm) maximum of `cos(x)` in interval: `8 < x < 9`: 127 | scc 'range(8, 9, 0.01) * cos || max' 128 | -0.1455 129 | 130 | // Integrate sin(x) from 0 to pi. Object 'plus_' is shortcut for std::plus() 131 | scc 'auto d=0.001; (range(0,pi,d) * sin || plus_) * d' 132 | 2 133 | 134 | // Concatenate vector of strings 135 | scc 'vstr V{"aaa", "bb", "cccc"}; V || plus_' 136 | aaabbcccc 137 | 138 | // Total length of strings in vector of strings 139 | scc 'vstr V{"aaa", "bb", "cccc"}; V * size || plus_' 140 | 9 141 | 142 | // Assign to c-string, then append `"XYZ"` and then remove `"bc"` substring : 143 | scc 'char s[99]; range(s) = "abc"; (range(s) << "XYZ") - "bc"' 144 | aXYZ 145 | 146 | // Remove non alpha-num characters and convert to upper case 147 | scc '(range("abc-123, xyz/") | isalnum) * toupper' 148 | ABC123XYZ 149 | 150 | // Hide phone number: 151 | scc "str S=\"John Q Public (650)1234567\"; S|isdigit='X'; S" 152 | John Q Public (XXX)XXXXXXX 153 | 154 | ----------------------------------------------------------------------------------------- 155 | 156 | 157 | 158 | Requires: +++ C++11 +++ compiler. Oldest tested compilers: GCC-4.7.2, GCC-4.8, CLANG-3.2 159 | 160 | In order to use it, you need to install it, and tell SCC where to look for its 161 | include files if it is installed in directory which is not searched by default 162 | by compiler. 163 | 164 | Options `-s` / `-S` can enable/disable this module. Set environment variable 165 | `scc_RO` (to any value) enables it. 166 | 167 | If enabled its print operator will be used instead of `std::cout` to print last 168 | statement-expression. 169 | 170 | 171 | 172 | AWK Module 173 | ~~~~~~~~~~ 174 | 175 | This is module that is bundled with SCC. It can be 176 | disabled if for example your compiler can not compile it for some reason. 177 | Options `-a` / `-A` enable/disable it. Set environment variable 178 | `scc_AWK` (to any value) enables it. 179 | 180 | 181 | AWK module allows stream processing - similar to real AWK. 182 | 183 | Syntax is not exactly AWK's, it is still +++C++ +++, but it is quite similar. 184 | 185 | Biggest difference is script layout. AWK's script have following 186 | elements (simplified): 187 | 188 | ---------------------------------------------------------------------------- 189 | awk 'BEGIN{begin-expr}; {per-record-expr}; END{end-expr}' 190 | ---------------------------------------------------------------------------- 191 | 192 | SCC have two alternatives for above. First is explicit while-loop: 193 | 194 | ---------------------------------------------------------------------------- 195 | scc 'begin-expr; WRL per-record-expr; end-expr;' 196 | ---------------------------------------------------------------------------- 197 | 198 | Shortcut `WRL` expands to `while(read_line())`. 199 | Function `read_line()`, reads input line and splits it into fields. 200 | 201 | Second alternative is to use options `-n` and `-p`. 202 | With `-n`, record is read, split into fields and snippet is evaluated for every 203 | record. With `-p`, additionally all fields are printed after snippet was 204 | evaluated. These are equivalent to PERL's and 205 | are convenient when we do not have _begin-expr_ and _end-expr_. 206 | 207 | ---------------------------------------------------------------------------- 208 | scc -n 'per-record-expr;' 209 | ---------------------------------------------------------------------------- 210 | 211 | Fortunately, GCC and CLANG allows use of `$` in identifiers, so AWK's dollar 212 | variables (`$0`, `$1`, `$NF`) are valid in SCC. 213 | 214 | In SCC, line's fields are of special string type `fld`, it is similar to `std::string` but it can be 215 | used in arithmetic expressions - they can be implicitly converted to corresponding numeric type. And it 216 | can be assigned a numeric value. That is `fld` behave like AWK's vars. 217 | Numeric types are any of `int`, `float`, etc. 218 | 219 | -------------------------------- 220 | fld f("1"); 221 | int i; 222 | 223 | i = f; // 1 224 | i = f+1; // 2 225 | f = 2; // "2" 226 | f + " m/s" // "2 m/s" 227 | f + 5 // "7" 228 | --------------------------------- 229 | 230 | SCC supports following AWK's global variables: 231 | 232 | * `$` - derived from `std::deque` — line's fields 233 | * `NF` - `long`, number of fields (set after read_line()) 234 | * `NR` - `long`, number of records read so far (set after read_line()) 235 | * `OFS` - `strr`, output field separator (another special type - string reference). 236 | * `FS` - `strr`, input field separator. 237 | * `ORS` - `strr`, output record separator 238 | * `RS` - `strr`, input record separator. 239 | * `FILENAME` - `const char[]`, current filename being processed 240 | 241 | 242 | More examples. Sum-up `DF(1)` used-disk-space column. In AWK and SCC: 243 | 244 | ---------------------------------------------------------------------------- 245 | df | awk '{n+=$3}; END{print n}' 246 | 31399199 247 | 248 | df | scc 'WRL n+=$3; n' 249 | 31399199 250 | ---------------------------------------------------------------------------- 251 | 252 | We can also replace column number with symbolic name (from `df` output header): 253 | 254 | ---------------------------------------------------------------------------- 255 | df | scc -H 'WRL n+=$("Used"); n' 256 | 31399199 257 | ---------------------------------------------------------------------------- 258 | 259 | Prepend line number to every line. 260 | 261 | ---------------------------------------------------------------------------- 262 | echo -e 'aaa\nbbb' | scc -p NR 263 | 1 aaa 264 | 2 bbb 265 | ---------------------------------------------------------------------------- 266 | 267 | For every line: first `NR` is printed (notice that there is no semicolon), 268 | then `$0`. 269 | 270 | Now lets make comma separated fields out of colon separated. Option `-o` sets `OFS` 271 | (output field separator), `-F` - set `FS` Snippet is empty in this example. 272 | 273 | ---------------------------------------------------------------------------- 274 | echo 1:2:3 | scc -F: -o, -p 275 | 1,2,3 276 | ---------------------------------------------------------------------------- 277 | 278 | Or equivalent: 279 | 280 | ---------------------------------------------------------------------------- 281 | echo 1:2:3 | FS=: OFS=, scc -p 282 | 1,2,3 283 | ---------------------------------------------------------------------------- 284 | 285 | 286 | //////////////////////////////////////////////////////////////////////////////////// 287 | Replace `"-"` or `"none"` with `"n/a"` in 2nd column using `std::regex`. In AWK and SCC: 288 | 289 | --------------------------------------------------------------------------- 290 | echo -e '1 -\n2 none\n3 abc' | awk '{gsub(/^(none|-)$/,"n/a",$2); print $0}' 291 | 1 n/a 292 | 3 n/a 293 | 4 abc 294 | 295 | echo -e '1 -\n2 none\n3 abc' | scc -p 'if ($2 == "(none|-)"_R) $2="n/a";' 296 | 1 n/a 297 | 3 n/a 298 | 4 abc 299 | ---------------------------------------------------------------------------- 300 | 301 | 302 | 303 | C-string with `_R` suffix are `std::regex` literal. The `operator==` calls `std::regex_match()`. 304 | Unfortunately GCC's LIBSTDC not yet +++ C++11 +++ compliant. Algorithms 305 | `std::regex_replace` and `std::regex_search` are not implemented yet in 306 | LIBSTDC++ and we have to use `if`. 307 | //////////////////////////////////////////////////////////////////////////////////// 308 | 309 | 310 | OpenCV Module 311 | ------------- 312 | 313 | Provides complete OpenCV environment. SCC with OpenCV module provides similar functionaly to ImageMagick. 314 | Off by default. Turn on with `--cv` o `--oc` options. Or set 315 | environmental vaiable `I`. 316 | 317 | 318 | Reads leng.png, and displays it: 319 | 320 | ----------------------------------------------------------------------------------------- 321 | scc --cv 'Mat I(imread("lena.png")); imshow("",I); waitKey();' 322 | ----------------------------------------------------------------------------------------- 323 | 324 | Same but using global enviromental varibale `I`: 325 | 326 | ----------------------------------------------------------------------------------------- 327 | I=lena.png 328 | scc --cv 'imshow("",I); waitKey();' 329 | ----------------------------------------------------------------------------------------- 330 | 331 | Same but instead of global, we will use temporary (with scc lifetime) env variable: 332 | 333 | ----------------------------------------------------------------------------------------- 334 | unset I // now global I is not set 335 | I=lean.png scc --cv 'imshow("",I); waitKey();' 336 | ----------------------------------------------------------------------------------------- 337 | 338 | Same with using SCC's `show()` function: 339 | 340 | ----------------------------------------------------------------------------------------- 341 | I=lean.png scc --cv 'show(I);' 342 | ----------------------------------------------------------------------------------------- 343 | 344 | Environmental variale `I` and `--cv` options enable earch other. If only one 345 | is set, second will be set automaticly. When `I` is set, we don't need to set `--cv` too. 346 | If `--cv` is pesent but `I` is unset, SCC reads `lena.png` into `I`. 347 | (TODO: frome what dir?) 348 | 349 | Convert to TIFF: 350 | 351 | --------------------------------------------------------------------------------------- 352 | scc --cv 'imwrite("lena.tif",I)' 353 | ----------------------------------------------------------------------------------------- 354 | 355 | Resize, make x2 times smaller: 356 | 357 | ----------------------------------------------------------------------------------------- 358 | scc --cv 'cv::resize(I,I,Size{},0.5,0.5); imwrite("small.png",I);' 359 | ----------------------------------------------------------------------------------------- 360 | 361 | Add noise: 362 | 363 | --------------------------------------------------------------------------------------- 364 | scc --cv 'asI(R); randn(R,0,50); show(I+R);' 365 | ----------------------------------------------------------------------------------------- 366 | 367 | Shortcut `asI` declares a cv::Mat with the same type and size as I. 368 | 369 | Edge detector: 370 | 371 | ----------------------------------------------------------------------------------------- 372 | scc --cv 'Mat E; cv::Canny(I,E,10000,35000, 7); show(E);' 373 | ----------------------------------------------------------------------------------------- 374 | 375 | 376 | 377 | Install 378 | ------- 379 | 380 | ----------------------------------------- 381 | git clone http://github.com/lvv/scc scc 382 | cd scc 383 | echo "PATH+=:$PWD/scc/" >> ~/.profile 384 | . ~/.profile 385 | scc '"SCC is installed"' 386 | --------------------------------------- 387 | 388 | With no or empty config, all optional modules will be disabled, and default compiler will be GCC. 389 | 390 | There is `scc/example_config` which you can copy (and edit) into one of: `/etc/scc`, 391 | `~/.scc` or `.scc`. 392 | 393 | GCC Pre-compiled headers 394 | ~~~~~~~~~~~~~~~~~~~~~~~~ 395 | For GCC you can enable precompiled headers, which will allow slightly (20%) faster compile. 396 | This is not recommended if you are going to update SCC or GCC. 397 | Command `scc -make-gch` will create directory `.gch` with precompiled headers: 398 | 399 | ----------------- 400 | cd path-to-scc-home 401 | scc --make-gch 402 | ls -l .gch 403 | ----------------- 404 | 405 | You need re-generate pre-compiled headers if SCC or GCC install was modified. 406 | To disable pre-compiled headers, run `rm -rf gch`. 407 | 408 | 409 | Status 410 | ------ 411 | 412 | Parser which extracts last +++ C++ +++ statement from snippet is semi-broken. 413 | It sometimes incorrectly parse (to extract last expression) multi-line scripts 414 | or expressions with "{}". See `u-sed` file for details. As workaround 415 | terminate every line with semicolon (even comment-line) and do not use 416 | print-if-not-terminated-with-semicolon feature. 417 | 418 | Regex in `RS`/`FS` are currently not supported (but were in v0.1) 419 | 420 | AWK module should be fixed to handle white space exactly like AWK. 421 | 422 | 423 | 424 | == Refs 425 | 426 | * httpx://en.wikipedia.org/wiki/Delimiter[Delimiter] 427 | * httpx://en.wikipedia.org/wiki/Comma-separated_values[CSV] 428 | * httpx://home.vrweb.de/~juergen.kahrs/gawk/XML/[XMLgawk] 429 | * httpx://en.wikipedia.org/wiki/Awk[Awk] 430 | * httpx://people.cs.uu.nl/piet/docs/nawk/nawk_23.html[Awk: Specifying how Fields are Separated] 431 | * httpx://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x[LIBSTDC++ status +++C++11+++] 432 | * httpx://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=286[Why I Hate Namespaces] 433 | * httpx://www.gotw.ca/publications/mill17.htm[Why Not Specialize Function Templates?] 434 | * httpx://richardminerich.com/2012/07/functional-programming-is-dead-long-live-expression-oriented-programming/[Functional Programming is Dead, Long Live Expression-Oriented Programming] 435 | 436 | 437 | //////////////// 438 | 439 | new 440 | EDA 441 | histogram -- https://github.com/visionmedia/histo 442 | python awk -- https://github.com/alecthomas/pawk 443 | serialization -- http://uscilab.github.io/cereal/ 444 | 445 | STRING 446 | https://github.com/facebook/folly/blob/master/folly/docs/FBString.md 447 | 448 | MAP 449 | TRIE 450 | http://login2win.blogspot.com/2011/06/c-tries.html 451 | 452 | HASH_MAP 453 | http://msinilo.pl/blog/?p=170 454 | fastest -- http://code.google.com/p/rdestl/ 455 | http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/ 456 | http://attractivechaos.wordpress.com/2008/09/12/the-google-hash-table-library/ 457 | http://www.augustana.ca/~mohrj/courses/1999.fall/csc210/lecture_notes/hashing.html 458 | http://svn.python.org/view/python/trunk/Objects/dictnotes.txt?view=markup&pathrev=53782 459 | http://stackoverflow.com/questions/11614106/is-gcc-stdunordered-map-implementation-slow-if-so-why 460 | 461 | REF STRING 462 | http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3609.html 463 | 464 | BENCHMARKS 465 | A Benchmark for Reading Flat Files Into Memory for Awk, Python, Perl, Java, and Ruby (steve.80cols.com) 466 | http://www.reddit.com/r/programming/comments/pub98/a_benchmark_for_reading_flat_files_into_memory/ 467 | v2 -- http://steve.80cols.com/flat_file_bakeoff.html 468 | v1 -- http://steve.80cols.com/reading_flat_files_into_memory_benchmark.html 469 | https://github.com/lorca/flat_file_benchmark/watchers 470 | 471 | read/fread/mmpa -- http://lemire.me/blog/archives/2012/06/26/which-is-fastest-read-fread-ifstream-or-mmap/ 472 | 473 | PARSING C++ 474 | http://www.codesynthesis.com/~boris/blog/2010/05/03/parsing-cxx-with-gcc-plugin-part-1/ 475 | http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang/ 476 | 477 | STL 478 | map adapter: https://github.com/krig/k11/blob/master/src/tests/iter.cpp 479 | 480 | GNU AWK 481 | Specifying how Fields are Separated -- http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_23.html 482 | one liners -- http://www.gnu.org/s/gawk/manual/gawk.html#One_002dshot 483 | 484 | STR TO INT 485 | http://www.partow.net/programming/strtk/index.html 486 | https://github.com/facebook/folly/blob/master/folly/docs/Conv.md 487 | http://www.kumobius.com/2013/08/c-string-to-int/ 488 | 489 | 490 | TOKENIZER 491 | http://www.codeproject.com/KB/recipes/Tokenizer.aspx 492 | FORMATS 493 | ALL 494 | http://dev.umpirsky.com/list-of-all-countries-in-all-languages-and-all-data-formats/ 495 | https://github.com/simonask/reflect 496 | 497 | JSON 498 | https://github.com/hjiang/jsonxx 499 | jq is like sed for JSON data -- http://stedolan.github.io/jq/ 500 | json parse in spirit -- http://boost-spirit.com/repository/applications/json_spirit.zip 501 | http://www.kirit.com/Blog:/2008-03-31/Thoughts%20on%20TinyJSON 502 | http://www.kirit.com/Thread:/1723074 503 | http://stackoverflow.com/questions/245973/whats-the-best-c-json-parser 504 | http://stackoverflow.com/a/8560856 505 | https://github.com/udp/json-parser 506 | http://zserge.bitbucket.org/jsmn.html 507 | http://stackoverflow.com/questions/8216743/how-to-read-big-json 508 | 509 | CSV 510 | http://csvkit.readthedocs.org/en/latest/index.html 511 | http://www.partow.net/programming/strtk/index.html 512 | http://blog.johantibell.com/2012/11/streaming-and-incremental-csv-parsing.html 513 | XML 514 | xml parser in spirit 515 | -- http://boost-spirit.com/repository/applications/xml.zip 516 | -- http://boost-spirit.com/repository/applications/Arabica.html 517 | http://zenxml.sourceforge.net/ 518 | awk xml -- http://pastebin.com/Vwvz3gzb 519 | http://www.artima.com/cppsource/xml_data_binding.html 520 | http://www.grinninglizard.com/tinyxml/ 521 | http://stackoverflow.com/questions/170686/best-open-xml-parser-for-c 522 | http://rapidxml.sourceforge.net/ 523 | http://www.codeguru.com/cpp/data/data-misc/xml/article.php/c19341 524 | ----------- 525 | There is a boost::xml in the sandbox and it's very good. We use 526 | TinyXML++ (which is decent) here but boost::xml was preferred; it was 527 | just too likely to change 528 | S-Expressions 529 | http://shinkirou.org/blog/2010/06/s-expressions-the-fat-free-alternative-to-json/ 530 | ENCODING 531 | Boost.Unicode: Aims at providing the foundation tools to 532 | accurately represent and deal with natural text in C++ in a 533 | portable and robust manner, so as to allow internationalized 534 | applications, by implementing parts of the Unicode Standard. 535 | (see (svn.boost.org/trac/boost/wiki/…;) 536 | 537 | This is already included as part of C++03. It's 538 | provided by the std::codecvt facet of the locale 539 | library 540 | 541 | Take a look on Boost.Locale it is a part of it 542 | DB 543 | http://tildeslash.com/libzdb/# 544 | SQL parser in spriti -- http://boost-spirit.com/repository/applications/spirit_sql.zip 545 | SQL connectors -- http://www.reddit.com/r/cpp/comments/mrbc5/how_to_connect_to_an_sql_database/ 546 | http://soci.sourceforge.net/ 547 | https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.RDB 548 | http://webtoolkit.eu/wt#/blog/2009/11/26/wt__dbo__an_orm__c___style 549 | http://code.google.com/p/hiberlite/ 550 | http://kahimyang.info/kauswagan/howto_blogs/1326-a_simple_c_c___database_daemon 551 | sqlite - https://github.com/catnapgames/NLDatabase 552 | ------------------ 553 | Regarding boost::sql proposal, there is some work in progress: 554 | * On BoostCon'09 Jeff Garland led workshop: Library in Week 2009 to discuss the std::rdb propsals, here are materials std::rdb (.tgz package) 555 | * std_rdb - Boost sister mailing list to discuss standard rdb proposal(s) 556 | * SOCI has been discussed in frame of the std::rdb mailing list and the workshop 557 | FILESYSTEM 558 | boost filesystem -- http://stackoverflow.com/questions/13897401/boost-filesystem-incredibly-slow 559 | 560 | 561 | vim: ft=asciidoc 562 | /////////////////////////////////// 563 | -------------------------------------------------------------------------------- /loops_macro.h: -------------------------------------------------------------------------------- 1 | #ifndef SCC_LOOPS_MACRO_H 2 | #define SCC_LOOPS_MACRO_H 3 | 4 | ///////////////////////////////////////////////////////////////////// LOOPS 5 | 6 | 7 | #define FOR(i,i0,N) for (long i = (i0), max_##i=(N); i < max_##i; i++) 8 | #define FOR1(i,N) FOR(i,1,N+1) 9 | #define ROF(i,a,b) for (long i = (b)-1; i >= long(a); i--) 10 | #define REP(N) for (long i_REP_ue923u=0, N_REP_2uf23f=(N); i_REP_ue923u< N_REP_2uf23f; i_REP_ue923u++) 11 | 12 | #define iFOR(N) FOR(i,0,N) 13 | #define jFOR(N) FOR(j,0,N) 14 | #define lFOR(N) FOR(l,0,N) 15 | #define kFOR(N) FOR(k,0,N) 16 | #define tFOR(N) FOR(t,0,N) 17 | #define nFOR(N) FOR(m,0,N) 18 | #define mFOR(N) FOR(m,0,N) 19 | 20 | #define iFOR1(N) FOR(i,1,N+1) 21 | #define jFOR1(N) FOR(j,1,N+1) 22 | #define kFOR1(N) FOR(k,1,N+1) 23 | #define tFOR1(N) FOR(t,1,N+1) 24 | #define nFOR1(N) FOR(m,1,N+1) 25 | #define mFOR1(N) FOR(m,1,N+1) 26 | 27 | #define ijFOR(I,J) iFOR(I) jFOR(J) 28 | 29 | #define ITER(IT, C) for (auto IT=begin(C); IT != end(C); IT++) 30 | #define RETI(IT, C) for (auto IT=end(C)-1; IT >= begin(C); IT--) 31 | #define itITER(C) ITER(it,C) 32 | #define itRETI(C) RETI(it,C) 33 | #define pITER(C) ITER(p,C) 34 | #define qITER(C) ITER(q,C) 35 | #define pRETI(C) RETI(p,C) 36 | 37 | #define IDX(I,C) for (long I=0; I<(long)(end(C)-begin(C)); I++) 38 | #define iIDX(C) IDX(i,C) 39 | #define jIDX(C) IDX(j,C) 40 | #define kIDX(C) IDX(k,C) 41 | #define lIDX(C) IDX(l,C) 42 | #define mIDX(C) IDX(m,C) 43 | #define nIDX(C) IDX(n,C) 44 | 45 | #define ALL(EL,C) for (auto& EL:C) 46 | #define cALL(C) for (auto c:C) if(c == '\0') break; else 47 | #define xALL(C) ALL (x,C) 48 | #define eALL(C) ALL (e,C) 49 | 50 | #ifdef RO_H 51 | #define xRNG(a,b,c) for (auto x: range(a,b,c)) 52 | #endif 53 | 54 | #endif // SCC_LOOPS_MACRO_H 55 | -------------------------------------------------------------------------------- /main.cc: -------------------------------------------------------------------------------- 1 | 2 | // do not define ctype funcs as macros (gcc specific) 3 | # define __NO_CTYPE 1 4 | 5 | #include "scc/cj.h" 6 | 7 | #ifdef scc_RO 8 | #include 9 | using namespace ro; 10 | #endif 11 | 12 | #include 13 | 14 | #include 15 | 16 | 17 | //#include "scc/matrix.h" 18 | #ifdef scc_BENCHMARK 19 | #include "lvv/timer.h" 20 | #endif 21 | 22 | #ifdef scc_AWK 23 | void print_line() { 24 | if (!F.empty()) cout << F[0]; 25 | for(int i=1; i < (int)F.size(); i++) 26 | cout << OFS << F[i]; 27 | cout << ORS; 28 | } 29 | 30 | struct buf_t; 31 | static buf_t *buf; 32 | 33 | static bool read_line() { return buf->get_rec(RS, FS, F); }; 34 | static bool next_file() { return buf->next_file(); }; 35 | #define WRL while( read_line() || (next_file() && read_line()) ) 36 | #endif 37 | 38 | 39 | struct tracking_buf_t : std::streambuf { 40 | 41 | char last_char; 42 | std::streambuf* buf; 43 | long count; 44 | 45 | tracking_buf_t (std::streambuf* buf) : last_char(0), buf(buf), count(0) { 46 | setp(0, 0); // no buffering, overflow on every char 47 | } 48 | 49 | bool terminated_line() const { return last_char=='\n' || count==0; } // TOFIX? compare with ORS (=="\n") 50 | 51 | virtual int_type overflow(int_type c) { 52 | buf->sputc(c); 53 | last_char = c; 54 | ++count; 55 | return c; 56 | } 57 | }; 58 | 59 | #include "snippet.h" 60 | 61 | int main(int argc, char** argv) { 62 | 63 | 64 | // tracking streambuf 65 | std::cout.flush(); 66 | std::streambuf* org_cout_buf = std::cout.rdbuf(); 67 | tracking_buf_t tracking_buf(org_cout_buf); 68 | std::cout.rdbuf(&tracking_buf); 69 | 70 | // pre-declared vars 71 | int i __attribute__((unused)) = 0; 72 | int j __attribute__((unused)) = 0; 73 | int k __attribute__((unused)) = 0; 74 | int n __attribute__((unused)) = 0; 75 | int m __attribute__((unused)) = 0; 76 | int l __attribute__((unused)) = 0; 77 | int t __attribute__((unused)) = 0; 78 | 79 | double x __attribute__((unused)) = 0.0; 80 | double y __attribute__((unused)) = 0.0; 81 | double z __attribute__((unused)) = 0.0; 82 | 83 | std::string s __attribute__((unused)); 84 | std::string w __attribute__((unused)); 85 | char c __attribute__((unused)); 86 | char *p __attribute__((unused)) = 0; 87 | char *q __attribute__((unused)) = 0; 88 | 89 | // facet / locale 90 | // to figure out 91 | std::locale::global(std::locale("")); 92 | std::wcout.imbue(std::locale()); 93 | auto& facet __attribute__((unused)) = std::use_facet>(std::locale()); 94 | 95 | 96 | #ifdef scc_AWK 97 | char **first_file_argv = argv+1; 98 | 99 | buf = new buf_t(first_file_argv, argv+argc); // stdio 100 | // cin.sync_with_stdio(false); 101 | 102 | //////// READ ENV 103 | 104 | // RS 105 | p = std::getenv("RS"); 106 | if (p==nullptr) RS = strr("\n"); 107 | else RS = strr(p); 108 | 109 | // ORS 110 | p = std::getenv("ORS"); 111 | if (p==nullptr) ORS = strr(RS); 112 | else ORS = strr(p); 113 | 114 | // FS 115 | #ifndef scc_ifs 116 | p = std::getenv("FS"); 117 | if (p==nullptr) FS = strr(" "); 118 | else FS = strr(p); 119 | #endif 120 | 121 | // OFS 122 | #ifndef scc_OFS 123 | p = std::getenv("OFS"); 124 | if (p==nullptr) OFS = strr(FS); 125 | else OFS = strr(p); 126 | #endif 127 | 128 | // PAD 129 | #ifndef scc_PAD 130 | p = std::getenv("PAD"); 131 | if (p==nullptr) PAD = strr(" \t"); 132 | else PAD = strr(p); 133 | #endif 134 | 135 | // PAD_tab 136 | for (const char *p = PAD.b; p!=PAD.e; p++) 137 | PAD_tab[size_t(*p)] = 1; 138 | 139 | #else // ^NOAWK 140 | #define ORS "\n" 141 | #endif // ^NOAWK 142 | 143 | // BENCHMARK 144 | #ifdef scc_BENCHMARK 145 | lvv::timer_t timer __attribute__((unused)) (true); 146 | #endif 147 | 148 | #ifdef scc_OPENCV 149 | 150 | cv::Mat F; 151 | cv::Mat Fbw; 152 | cv::Mat M,O; 153 | 154 | #ifdef scc_I_path 155 | cv::Mat I (cv::imread(scc_I_path)); 156 | cv::Mat Ibw (cv::imread(scc_I_path, CV_LOAD_IMAGE_GRAYSCALE)); 157 | #else 158 | cv::Mat I (cv::imread("/home/lvv/p/cv/lena.png")); 159 | cv::Mat Ibw (cv::imread("/home/lvv/p/cv/lena.png", CV_LOAD_IMAGE_GRAYSCALE)); 160 | #endif 161 | 162 | if (I.empty()) 163 | CV_Error(CV_StsBadArg, "error: Cann't read input image. Try to adjust image path"); 164 | 165 | I .convertTo (F, CV_32FC3, 1.f/255); 166 | Ibw.convertTo (Fbw, CV_32FC1, 1.f/255); 167 | 168 | 169 | #define asI(M) cv::Mat M(I.size(), I.type(), cv::Scalar::all(0)); 170 | #define Isz I.size() 171 | #define Fsz I.size() 172 | #endif 173 | 174 | { /////////////////////////////////////////////////////////////////////////////////// snippet env 175 | 176 | #ifdef scc_IS_STREAM 177 | #ifdef scc_AWK 178 | if (is_header) { 179 | read_line(); 180 | for (size_t i = 0; i 6 | using std::cout; 7 | using std::endl; 8 | #include 9 | using std::vector; 10 | //#include 11 | 12 | //using namespace std; 13 | 14 | struct pt { 15 | int x, y; 16 | pt (){}; 17 | pt (int x, int y) : x(x), y(y) {}; 18 | bool operator== (pt rhs) { return x==rhs.x && y==rhs.y; }; 19 | bool operator!= (pt rhs) { return ! (*this == rhs); }; 20 | pt operator+ (pt rhs) { return pt(x+rhs.x, y+rhs.y); }; 21 | pt& operator+= (pt rhs) { x+=rhs.x; y+=rhs.y; return *this; }; 22 | static pt up () { return pt(0,-1);}; 23 | static pt right () { return pt(1,0);}; 24 | static pt down () { return pt(0,1);}; 25 | static pt left () { return pt(-1,0);}; 26 | }; 27 | 28 | 29 | template 30 | std::ostream& operator<< (std::ostream& os, const pt& P) { os << "(" << P.x << "," << P.y << ")"; return os; }; 31 | 32 | 33 | template > class Rg=std::vector> 34 | struct matrix { 35 | //typedef typename vector::iterator iterator ; 36 | //typedef typename vector::const_iterator const_iterator ; 37 | size_t w_,h_; 38 | vector V; 39 | explicit matrix (size_t h, size_t w, T val0=0) : w_(w), h_(h), V(h*w, val0) {}; 40 | T& operator() (pt p) { return V[w_ * p.y + p.x]; }; 41 | T& operator() (size_t x, size_t y) { return V[w_ * y + x]; }; 42 | const T&operator() (size_t x, size_t y) const { return V[w_ * y + x]; }; 43 | size_t h () const { return h_; }; 44 | size_t w () const { return w_; }; 45 | bool in (pt p) const { return 0<=p.y && p.y < (T)h() && 0<=p.x && p.x < (T)w() ; }; 46 | bool on_cell (pt p) const { return 0<=p.y && p.y < (T)h() && 0<=p.x && p.x < (T)w() ; }; 47 | bool on_grid (pt p) const { return 0<=p.y && p.y <= (T)h() && 0<=p.x && p.x < (T)w() ; }; 48 | bool on_border (pt p) const { return 0==p.y || (T)h()==p.y || p.x==0 || (T)p.x==w() ; }; 49 | bool next (pt& p) { pt pn; pn.x = (p.x+1)%w(); pn.y = p.y+(pn.x 53 | std::istream& 54 | operator>> (std::istream& is, matrix& M) { 55 | for(size_t j=0; j> M(i,j))) break; 58 | return is; 59 | }; 60 | 61 | template 62 | std::ostream& 63 | operator<< (std::ostream& os, const matrix& M) { 64 | for(size_t j=0; j&1) | sed -n '/^gcc version/s/^gcc version \([.0-9]*\) .*/\1/p'` " 161 | echo "CXXFLAGS: ${CXXFLAGS}" 162 | fi 163 | 164 | 165 | if [[ -z $snippet_file ]] ; then 166 | snippet_file=$tmpdir/snippet.scc 167 | echo "${1%% }" > $snippet_file 168 | shift 1 169 | fi 170 | 171 | 172 | # wrap last statment into "cout << (last_statement) << endl;" 173 | #cat $snippet_file | sed 's/.*;;//;s/$//;s/[ \t]*$//;s/\(.*[;}]\)*\([^;}]\+$\)/\1 out(), \2 ; is_print_last=true;/' > $snippet_cc 174 | 175 | cat $snippet_file | 176 | 177 | # this shouldn't be sed 178 | sed -r ' 179 | s|//.*$||; 180 | s|/\*[^*]*\*/||; 181 | s/.*;;// 182 | s/$//; 183 | s/\/\/.$//; 184 | s/[ \t]*$//; 185 | s/[\n]/\t/g; 186 | /^$/d; 187 | s/(.*[;])*([^;]+$)/ \1 '$scc_PRINTER' ( \2 ) '$scc_PRINTER_END'; is_print_last=true; / 188 | ' > $snippet_cc 189 | 190 | # split file scope part 191 | cat $snippet_file | sed -n 's/\(;;\).*/;/p' > $snippet_h 192 | 193 | 194 | ##################################################################################### GENERATE SRC 195 | 196 | 197 | 198 | ${CXX-$default_CXX} $CXXFLAGS $main_cc -o $main_exe $LDFLAGS $LIBS || exit 1 199 | 200 | if [[ $execute == 1 ]] ; then 201 | LCC_ALL=C $time $main_exe "$@" 202 | exit $? 203 | else 204 | exit 0 205 | fi 206 | 207 | # vim:set ts=8 sw=8 syntax=sh: 208 | -------------------------------------------------------------------------------- /scc.h: -------------------------------------------------------------------------------- 1 | #ifndef scc_SCC_H 2 | #define scc_SCC_H 3 | 4 | #include "scc/simple.h" 5 | //#include "scc/allocator.h" 6 | 7 | 8 | // BUF 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // CONFIG 16 | 17 | const static bool is_header = 18 | #ifdef scc_IS_HEADER 19 | true; 20 | #else 21 | false; 22 | #endif 23 | 24 | const static bool is_stream = 25 | #ifdef scc_IS_STREAM 26 | true; 27 | #else 28 | false; 29 | #endif 30 | 31 | static bool __attribute__((unused)) is_print_last = false; 32 | 33 | const static bool is_p = 34 | #ifdef scc_P 35 | true; 36 | #else 37 | false; 38 | #endif 39 | 40 | const static bool is_n = 41 | #ifdef scc_N 42 | true; 43 | #else 44 | false; 45 | #endif 46 | 47 | #ifdef scc_AWK 48 | #include 49 | #endif 50 | 51 | #ifdef scc_OPENCV 52 | #include 53 | using namespace cv; 54 | #include "cv.h" 55 | void show(Mat I) { cv::imshow("",I); waitKey(); }; 56 | #endif 57 | 58 | 59 | 60 | #endif // scc_SCC 61 | -------------------------------------------------------------------------------- /simple: -------------------------------------------------------------------------------- 1 | simple.h -------------------------------------------------------------------------------- /simple.h: -------------------------------------------------------------------------------- 1 | #ifndef SCC_SIMPLE_H 2 | #define SCC_SIMPLE_H 3 | 4 | 5 | // list af all C/C++ headers --- http://stackoverflow.com/questions/2027991/list-of-standard-header-files-in-c-and-c 6 | 7 | // GCC 8 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) 9 | #define CXX11 10 | #endif 11 | 12 | // CLANG 13 | #if defined(__clang__) 14 | #if __has_feature(cxx_decltype) 15 | #define CXX11 16 | #endif 17 | #endif 18 | 19 | // MSVC (not tested) 20 | #if defined(_MSC_VER) && _MSC_VER >= 1600 21 | #define CXX11 22 | #endif 23 | 24 | //////////////////////////////////////////////////////////////////// NUMERIC CONSTANTS 25 | const double e = 2.7182818284590452354; 26 | const double pi = 3.14159265358979323846; 27 | 28 | 29 | //////////////////////////////////////////////////////////////////// LVV 30 | 31 | /* 32 | namespace lvv { 33 | 34 | template T max(T value) { return value; } 35 | template T max(T first, Args... rest) { return std::max(first, lvv::max(rest...)); } 36 | 37 | template T min(T value) { return value; } 38 | template T min(T first, Args... rest) { return std::min(first, lvv::min(rest...)); } 39 | };*/ 40 | 41 | #include "scc/loops_macro.h" 42 | //////////////////////////////////////////////////////////////////// C 43 | 44 | //#include // inject info global namespace: div, ... 45 | 46 | // from cstdlib 47 | /* 48 | int rand(void); 49 | long random(void); 50 | double drand48(void); 51 | char* getenv(const char *); 52 | void exit(int); 53 | double atof(const char *); 54 | int atoi(const char *); 55 | long atol(const char *); 56 | long long atoll(const char *); 57 | */ 58 | //#include 59 | #include 60 | #include 61 | #include 62 | 63 | 64 | #include 65 | extern "C" void *memcpy(void *dest, const void *src, size_t n); 66 | 67 | #include 68 | //using std::abs; 69 | using std::floor; 70 | using std::ceil; 71 | using std::signbit; 72 | #ifdef CXX11 73 | using std::trunc; 74 | using std::round; 75 | #endif 76 | 77 | #include 78 | 79 | 80 | 81 | 82 | ///////////////////////////////////////////////////////////////////// C++ IO 83 | #include 84 | #include 85 | #include 86 | #include 87 | 88 | 89 | ///////////////////////////////////////////////////////////////////// C++ STL 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | #include 101 | #include 102 | #include 103 | #include 104 | 105 | #ifdef CXX11 106 | #include 107 | #include 108 | #include 109 | #include 110 | #include 111 | #endif 112 | 113 | ///////////////////////////////////////////////////////////////////// C++11 STL 114 | #ifdef CXX11 115 | #include 116 | #include 117 | #include 118 | #include 119 | #endif 120 | 121 | #ifdef scc_BOOST_BIND 122 | #include 123 | #endif 124 | 125 | #ifdef scc_BOOST_LAMBDA 126 | #include 127 | #endif 128 | 129 | 130 | ///////////////////////////////////////////////////////////////////// 131 | 132 | // io 133 | using std::cin; 134 | using std::basic_ostream; 135 | using std::istream; 136 | using std::ostream; 137 | using std::fstream; 138 | 139 | using std::cout; 140 | using std::cerr; 141 | using std::endl; 142 | using std::hex; 143 | using std::flush; 144 | using std::setw; 145 | using std::dec; 146 | using std::setprecision; 147 | 148 | using std::wcout; 149 | using std::wcin; 150 | 151 | // strings 152 | using std::string; 153 | using std::wstring; 154 | using std::basic_string; 155 | #ifdef CXX11 156 | using std::to_string; 157 | #endif 158 | 159 | // containers 160 | using std::vector; 161 | using std::deque; 162 | using std::set; 163 | using std::list; 164 | using std::multiset; 165 | using std::map; 166 | using std::multimap; 167 | using std::stringstream; 168 | using std::istringstream; 169 | using std::ostringstream; 170 | using std::numeric_limits; 171 | using std::ostream_iterator; 172 | using std::istream_iterator; 173 | using std::bitset; 174 | using std::stack; 175 | using std::queue; 176 | using std::priority_queue; 177 | #ifdef CXX11 178 | using std::array; 179 | using std::unordered_set; 180 | using std::unordered_multiset; 181 | using std::forward_list; 182 | using std::unordered_map; 183 | using std::unordered_multimap; 184 | #endif 185 | 186 | // algo 187 | using std::swap; 188 | using std::generate; 189 | using std::generate_n; 190 | 191 | // Non-modifying 192 | using std::for_each; 193 | using std::count; 194 | using std::count_if; 195 | using std::mismatch; 196 | using std::equal; 197 | using std::find; 198 | using std::find_if; 199 | using std::find_end; 200 | using std::find_first_of; 201 | using std::adjacent_find; 202 | using std::search; 203 | using std::search_n; 204 | 205 | // modifying 206 | using std::copy; 207 | using std::copy_backward; 208 | #ifdef CXX11 209 | using std::copy_if; //C++11 210 | #endif 211 | using std::fill; 212 | using std::fill_n; 213 | using std::transform; 214 | using std::generate; 215 | using std::generate_n; 216 | using std::remove; 217 | using std::remove_if; 218 | using std::remove_copy; 219 | using std::remove_copy_if; 220 | using std::replace; 221 | using std::replace_if; 222 | using std::replace_copy; 223 | using std::replace_copy_if; 224 | using std::swap; 225 | using std::swap_ranges; 226 | using std::iter_swap; 227 | using std::partition; 228 | using std::stable_partition; 229 | using std::reverse; 230 | using std::reverse_copy; 231 | using std::rotate; 232 | using std::rotate_copy; 233 | using std::random_shuffle; 234 | using std::unique; 235 | using std::unique_copy; 236 | 237 | // sort 238 | using std::sort; 239 | using std::partial_sort; 240 | using std::partial_sort_copy; 241 | using std::stable_sort; 242 | using std::nth_element; 243 | 244 | // binary search 245 | using std::lower_bound; 246 | using std::upper_bound; 247 | using std::binary_search; 248 | using std::equal_range; 249 | 250 | 251 | // set 252 | using std::merge; 253 | using std::inplace_merge; 254 | using std::includes; 255 | using std::set_difference; 256 | using std::set_intersection; 257 | using std::set_symmetric_difference; 258 | using std::set_union; 259 | 260 | 261 | // heap 262 | #ifdef CXX11 263 | using std::is_heap; // C++11 264 | #endif 265 | using std::make_heap; 266 | using std::push_heap; 267 | using std::pop_heap; 268 | using std::sort_heap; 269 | 270 | // min/max 271 | using std::max; 272 | using std::min; 273 | #ifdef CXX11 274 | using std::max_element; 275 | using std::min_element; 276 | using std::minmax; // C++11 277 | using std::minmax_element; // C++11 278 | #endif 279 | using std::lexicographical_compare; 280 | using std::next_permutation; 281 | using std::prev_permutation; 282 | 283 | // numeric 284 | using std::accumulate; 285 | using std::inner_product; 286 | using std::adjacent_difference; 287 | using std::partial_sum; 288 | 289 | 290 | // utils 291 | using std::pair; 292 | using std::make_pair; 293 | #ifdef CXX11 294 | using std::get; // C++11 295 | using std::tie; // C++11 296 | using std::tuple; // C++11 297 | using std::make_tuple; // C++11 298 | using std::tuple_size; // C++11 299 | using std::make_shared; // C++11 300 | using std::iota; // C++11 301 | using namespace std::chrono; 302 | #endif 303 | 304 | // iterator 305 | using std::advance; 306 | using std::distance; 307 | 308 | 309 | #ifdef CXX11 310 | using std::begin; // C++11 311 | using std::end; // C++11 312 | using std::prev; // C++11 313 | using std::next; // C++11 314 | using std::move_iterator; // C++11 315 | 316 | // memory (C++11) 317 | using std::shared_ptr; 318 | using std::unique_ptr; 319 | using std::auto_ptr; 320 | using std::weak_ptr; 321 | 322 | // function 323 | using std::function; 324 | #endif 325 | 326 | 327 | #ifdef scc_BOOST_LAMBDA 328 | using namespace boost::lambda; 329 | #endif 330 | 331 | 332 | #ifdef scc_BOOST_BIND 333 | using boost::bind; 334 | #else 335 | #ifdef CXX11 336 | using std::bind; 337 | #endif 338 | #endif 339 | 340 | using std::plus; 341 | using std::minus; 342 | using std::multiplies; 343 | using std::divides; 344 | using std::modulus; 345 | using std::negate; 346 | 347 | using std::less; 348 | using std::greater; 349 | using std::equal; 350 | using std::equal_to; 351 | using std::not_equal_to; 352 | using std::greater_equal; 353 | using std::less_equal; 354 | 355 | using std::bit_and; 356 | using std::bit_or; 357 | using std::bit_xor; 358 | 359 | using std::logical_and; 360 | using std::logical_or; 361 | using std::logical_not; 362 | 363 | using std::unary_negate; 364 | using std::binary_negate; 365 | 366 | using std::not1; 367 | using std::not2; 368 | 369 | #if defined(scc_BOOST_BIND) || defined(scc_BOOST_LAMBDA) 370 | // already in global namaspace 371 | #else 372 | #if !defined(scc_RO) && defined(CXX11) 373 | using std::placeholders::_1; 374 | using std::placeholders::_2; 375 | using std::placeholders::_3; 376 | using std::placeholders::_4; 377 | using std::placeholders::_5; 378 | #endif 379 | #endif 380 | 381 | // meta 382 | #ifdef CXX11 383 | using std::is_placeholder; 384 | using std::is_same; 385 | using std::is_base_of; 386 | using std::enable_if; 387 | using std::declval; 388 | #endif 389 | 390 | using std::input_iterator_tag; 391 | using std::output_iterator_tag; 392 | using std::forward_iterator_tag; 393 | using std::bidirectional_iterator_tag; 394 | using std::random_access_iterator_tag; 395 | 396 | 397 | ///////////////////////////////////////////////////////////////////// SHORTCUTS 398 | 399 | ///// types 400 | typedef double dbl; 401 | 402 | ///// Linux Kernel types 403 | typedef uint8_t u8; 404 | typedef uint16_t u16; 405 | typedef uint32_t u32; 406 | 407 | typedef int8_t i8; 408 | typedef int16_t i16; 409 | typedef int32_t i32; 410 | 411 | 412 | ///// STL containers types 413 | typedef std::vector vint; 414 | typedef std::vector vvint; 415 | typedef std::vector vuint; 416 | typedef std::vector vlong; 417 | typedef std::vector vulong; 418 | typedef std::vector vchar; 419 | typedef std::vector vfloat; 420 | typedef std::vector vdouble; 421 | typedef std::vector vdbl; 422 | typedef std::vector vvdbl; 423 | 424 | typedef std::deque dint; 425 | typedef std::deque dlong; 426 | typedef std::deque duint; 427 | typedef std::deque dfloat; 428 | typedef std::deque ddouble; 429 | typedef std::deque ddbl; 430 | typedef std::deque dchar; 431 | 432 | typedef std::list lint; 433 | typedef std::list luint; 434 | typedef std::list llong; 435 | typedef std::list lulong; 436 | typedef std::list lchar; 437 | typedef std::list lfloat; 438 | typedef std::list ldouble; 439 | typedef std::list ldbl; 440 | 441 | typedef std::string str; 442 | typedef std::vector vstr; 443 | typedef std::deque dstr; 444 | typedef std::list lstr; 445 | 446 | typedef std::set sint; 447 | typedef std::set slong; 448 | //typedef std::set schar; // conflict with OpenCV 449 | 450 | typedef std::multiset msint; 451 | typedef std::multiset mslong; 452 | typedef std::multiset mschar; 453 | 454 | 455 | ///// utils 456 | #define MT std::make_tuple 457 | //#define MP std::make_pair // conflicts with OpenCV 458 | 459 | #define GL(x) std::getline(cin,x) 460 | #define NL cin.ignore(numeric_limits::max(),'\n'); 461 | 462 | 463 | 464 | 465 | #ifdef RO_H 466 | using namespace ro; 467 | #else 468 | #undef _ 469 | #define _ std::cout<< 470 | #undef __ 471 | #define __ std::cout<< 472 | #endif 473 | 474 | 475 | #endif // SCC_SIMPLE_H 476 | -------------------------------------------------------------------------------- /u-all: -------------------------------------------------------------------------------- 1 | 2 | set -o errexit 3 | set -v 4 | 5 | . u-scc 6 | . u-strr 7 | . u-cj 8 | . u-awk 9 | . u-hasher 10 | . u-matrix 11 | 12 | : '= = = = = = = = = = = = = = = = = = = = = = = = ALL PASS = = = = = = = = = = = = = = = = = = = = = = = = =' 13 | -------------------------------------------------------------------------------- /u-awk: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | set -o errexit 5 | set -v 6 | 7 | : --------------------------------------------------------- PARSER 8 | echo -n ' 11 : 12!21 :22!31:32 : 33:' | PAD=' ' RS='!' scc -F: -p ; echo -e "\n11:12!21:22!31:32:33:!" 9 | 10 | : --------------------------------------------------------- FIELD 11 | echo -en '\n1 2\n11 22\n' | ORS=' / ' scc -p '$1=9;' ; echo -e "\n9 / 9 2 / 9 22" 12 | 13 | : --------------------------------------------------------- STREAM 14 | command df | scc 'WRL n+=$3; n' 15 | command df | awk '{n+=$3;}; END{print n}' 16 | 17 | : --------------------------------------------------------- SEPERATORS 18 | echo -n 11,,-,22--111,,222 | RS=-- ORS="(NL) " scc -p -i,, -o: ''; echo -e "\n11:-,22(NL) 111:222(NL)" 19 | 20 | #) 21 | #echo --------------------------------------------------------- REGEX 22 | #echo "echo -e \"1 -\n2\n3 none\n4 abc\" | scc -p 'F(1)=RR(F(1),R(\"^(none|-)?$\"),"n/a");'" 23 | # echo -e "1 -\n2\n3 none\n4 abc" | scc -p 'F(1)=RR(F(1),R( "^(none|-)?$" ),"n/a");' && 24 | #echo -e '\n1 n/a\n2 n/a\n3 n/a\n4 abc' 25 | 26 | #echo --------------------------------------------------------- 27 | #echo "echo -e 'aaa bbb\nccc ddd' | scc -p 'F.push_front(NR+1);'" 28 | # echo -e 'aaa bbb\nccc ddd' | scc -p 'F.push_front(NR+1);' && 29 | #echo -e '\n1 aaa bbb\n2 ccc ddd' 30 | 31 | #echo --------------------------------------------------------- FIELD 32 | #echo -e 'aaa bbb\nccc ddd' | scc -p 'field(NR+1)+" "' && 33 | #echo -e 'aaa bbb\nccc ddd' | scc -p 'field(NR+1)+" "' && 34 | #echo -e '\n1 aaa bbb\n2 ccc ddd' 35 | 36 | #echo --------------------------------------------------------- 37 | #echo -e "AA\nBB\nCC" | scc 'WRL if (RS(line, R(argv[1]))) cout << line << endl;' 'A|B' && 38 | #echo -e "\nAA\nBB" 39 | 40 | # --------------------------------------------------------- 41 | #scc 'str s="aa bb"; RR(s, R("(\\w+)"),"*\\1*")' && 42 | #echo -e "\n*aa* *bb*" 43 | 44 | #echo --------------------------------------------------------- 45 | #echo '"aa", "bb\"-, bb", "cc"' | scc 'IFS=CSV ; WRL for (str f:F) cout << f << endl;' && 46 | #echo -e "\naa\nbb\"-, bb\ncc" 47 | 48 | #echo --------------------------------------------------------- 49 | #echo 1:2:3 | scc -i: -o '","' -p 50 | #echo 1 2 3 | scc -I '"(\\S+)(\\s+|$)"' -o '","' -p 51 | 52 | -------------------------------------------------------------------------------- /u-cj: -------------------------------------------------------------------------------- 1 | 2 | set -o errexit 3 | set -v 4 | 5 | # gcd 6 | scc -a2 'std::integral_constant::value' 7 | 8 | # factorial 9 | scc -a1 'std::integral_constant::value' 10 | scc -a1 'std::integral_constant::value' 11 | scc -a6 'std::integral_constant::value' 12 | 13 | # permutation 14 | scc -a90 'std::integral_constant::value' 15 | scc -a3360 'std::integral_constant::value' 16 | 17 | # combination 18 | scc -a560 'std::integral_constant::value' 19 | 20 | # histogram 21 | scc -a1 's="asdfasdvasdfddkdkdk"; (histogram_vector(s) || plus()) == s.size()' 22 | scc -a1 's="asdfasdvasdfddkdkdk"; (histogram(s)*_1 || plus()) == s.size()' 23 | -------------------------------------------------------------------------------- /u-hasher: -------------------------------------------------------------------------------- 1 | 2 | scc 'bitset<8> bs(11); unordered_set> sbs; sbs << make_tuple(2,1); sbs' 3 | 4 | # gcc only, error with clang 5 | scc 'bitset<8> bs(11); unordered_set,int>> sbs; sbs << make_tuple(bs,1); sbs' 6 | 7 | -------------------------------------------------------------------------------- /u-matrix: -------------------------------------------------------------------------------- 1 | 2 | echo 1 2 3 4 5 | scc 'matrix M(2,2); cin >> M; cout << M << endl;' 3 | -------------------------------------------------------------------------------- /u-scc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | set -o errexit 5 | set -v 6 | 7 | scc 'int ff(int i){return 2*i;} ;; ff(2+2)' 8 | 9 | #################### TO RO 10 | # RO 11 | #: --------------------------------------------------------- PRINTER 12 | #scc 'vint vi{1}; int ca[]={1}; array ar{{1}}; const char* cs="CA"; str s="STR"; strr sr("SR"); fld f("FLD"); __ vi,ca,ar,cs,s,sr,f;' ; echo "{1} {1} {1} CS STR SR FLD" 13 | 14 | : --------------------------------------------------------- OI 15 | #scc "*oi = 1; *oi = 2; *oi ='a'; *oi='b'; *oi=pair(11,22); cout << endl;"; echo 1 2 a b ⟨11,22⟩ 16 | : --------------------------------------------------------- OI 17 | #scc 'vint A{1,2,3}; oi=A; str S("ABC"); oi=S; _ endl;'; echo 1 2 3 A B C 18 | 19 | ################################################################### 20 | 21 | 22 | 23 | 24 | 25 | : '- - - - - - - - - - - - - - - - - - - - - - - - U-SCC passed - - - - - - - - - - - - - - - - - - - - - - - - -' 26 | -------------------------------------------------------------------------------- /u-sed: -------------------------------------------------------------------------------- 1 | 2 | #cat <> \1 PRINT(\2);/' 3 | 4 | #cat <> \1 PRINT(\2);/ 7 | #' 8 | 9 | cat <> \1 PRINT(\2);/ 13 | ' 14 | 15 | 16 | print 17 | no-print; 18 | OK; print 19 | OK; no-print; 20 | OK; no-print; print 21 | OK; {} 22 | OK; {code-block;} 23 | OK; print_rvalue_t{1} 24 | OK; f(int{1}) 25 | OK; vint{1,2}; f() 26 | OK; vint{1,2}*1 27 | END 28 | 29 | # 30 | #FAIL; f(";") 31 | #FAIL; f(';') 32 | #FAIL; f("}") 33 | #FAIL; while(a){b;} no-print 34 | #FAIL; while(a) no-print 35 | #OK; for(a;b;c) {no-print} 36 | #FAIL; for(a;b;c) no-print 37 | -------------------------------------------------------------------------------- /u-strr: -------------------------------------------------------------------------------- 1 | 2 | set -o errexit 3 | set -v 4 | 5 | # TOADD 6 | 7 | #{ strr v ("abc"); _ "strr : ", v, "; "; cout << v << "\n"; }; 8 | #{ fld v ("abc"); _ "fld : ", v, "; "; cout << v << "\n"; }; 9 | 10 | scc ' 11 | //{ strr f("abc"); fld f2 (f); __ f2; }; 12 | { fld f; string s("abc"); f.assign(s.begin(), s.end()); __ f; }; 13 | 14 | { fld f("abc"); __ f; }; 15 | { fld f = "abc"; __ f; }; 16 | { fld f("abc"); fld f2 (f); __ f2; }; 17 | 18 | 19 | 20 | { fld f("abc"); fld f2 = f; __ f2; }; 21 | 22 | { fld s("1.23"); __ (double)s; }; 23 | { fld s("1.23"); __ (float)s; }; 24 | { fld s("1.23"); __ (int)s; }; 25 | { fld s("1.23"); __ (long)s; }; 26 | { fld s("1.23"); __ (int)(char)s; }; 27 | 28 | { fld s("3.33"); s=1; __ s; }; 29 | { fld s("3.33"); s=1l; __ s; }; 30 | { fld s("3.33"); s=1.f; __ s; }; 31 | 32 | { fld s("3.33"); __ s+7; }; 33 | { fld s("3.33"); __ 7+s; }; 34 | { fld s("3.33"); __ s+6.67; }; 35 | { fld s("3.33"); __ 6.67+s; }; 36 | { fld s("3.33"); __ fld("6.67")+s; }; 37 | 38 | { fld s("3.33"); __ (s+=7); }; 39 | { fld s("3.33"); __ (s+=6.67); }; 40 | 41 | { fld s("22.22"); __ (s-=12); }; 42 | { fld s("22.22"); __ (s-=12.22); }; 43 | 44 | ' 45 | 46 | 47 | scc 'fld s("1.11"); s+1' 48 | scc 'fld s("1.11"); s+1l' 49 | 50 | scc 'fld s("1.11"); s+1' 51 | scc 'fld s("1.11"); s=1.1' 52 | scc 'fld s("1.11"); s=1.1' 53 | scc 'fld s("1.11"); s+1.1' 54 | scc 'fld s("1.11"); s+2.22' 55 | scc 'fld s("1.11"); s+=2.22' 56 | scc 'fld s("1.11"); s=2.22' 57 | scc 'fld s("1.11"); s=1+2.22' 58 | scc 'fld s("1.11"); s+1.11' 59 | 60 | : '- - - - - - - - - - - - - - - - - - - - - - - - U-STR passed - - - - - - - - - - - - - - - - - - - - - - - - -' 61 | --------------------------------------------------------------------------------