From 43bfbaeaa16898c6268f583ae39ea74bcac7fd52 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 12 Apr 2023 11:45:35 +0530 Subject: [PATCH] Add SetChar to emulate std::set API --- src/libasr/containers.h | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/libasr/containers.h b/src/libasr/containers.h index 40b5292990..dff550dd8b 100644 --- a/src/libasr/containers.h +++ b/src/libasr/containers.h @@ -59,6 +59,49 @@ struct Vec { #endif } + template + typename std::enable_if::value, bool>::type present(Q x, size_t& index) { + for( size_t i = 0; i < n; i++ ) { + if( strcmp(p[i], x) == 0 ) { + index = i; + return true; + } + } + return false; + } + + template + typename std::enable_if::value, bool>::type present(Q x, size_t& index) { + for( size_t i = 0; i < n; i++ ) { + if( p[i] == x ) { + index = i; + return true; + } + } + return false; + } + + void erase(T x) { + size_t delete_index; + if( !present(x, delete_index) ) { + return ; + } + + for( int64_t i = delete_index; i < (int64_t) n - 1; i++ ) { + p[i] = p[i + 1]; + } + if( n >= 1 ) { + n = n - 1; + } + } + + void push_back_unique(Allocator &al, T x) { + size_t index; + if( !Vec::present(x, index) ) { + Vec::push_back(al, x); + } + } + void push_back(Allocator &al, T x) { // This can pass by accident even if reserve() is not called (if // reserve_called happens to be equal to vec_called_const when Vec is @@ -135,6 +178,55 @@ struct Vec { static_assert(std::is_standard_layout>::value); static_assert(std::is_trivial>::value); +/* +SetChar emulates the std::set API +so that it acts as a drop in replacement. +*/ +struct SetChar: Vec { + + bool reserved; + + SetChar(): + reserved(false) { + clear(); + } + + void clear() { + n = 0; + p = nullptr; + max = 0; + } + + void clear(Allocator& al) { + reserve(al, 0); + } + + void reserve(Allocator& al, size_t max) { + Vec::reserve(al, max); + reserved = true; + } + + void from_pointer_n_copy(Allocator &al, char** p, size_t n) { + reserve(al, n); + for (size_t i = 0; i < n; i++) { + push_back(al, p[i]); + } + } + + void from_pointer_n(char** p, size_t n) { + Vec::from_pointer_n(p, n); + reserved = true; + } + + void push_back(Allocator &al, char* x) { + if( !reserved ) { + reserve(al, 0); + } + + Vec::push_back_unique(al, x); + } +}; + // String implementation (not null-terminated) struct Str { size_t n;