From 076498028ff511afd88d93e7b0bf1d1a81093b3d Mon Sep 17 00:00:00 2001 From: B Stack Date: Tue, 13 Nov 2018 06:58:56 -0500 Subject: 10.6 --- zen/stl_tools.h | 63 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 15 deletions(-) (limited to 'zen/stl_tools.h') diff --git a/zen/stl_tools.h b/zen/stl_tools.h index c3a9bf8f..d8bda888 100755 --- a/zen/stl_tools.h +++ b/zen/stl_tools.h @@ -11,10 +11,11 @@ #include #include #include +#include #include #include #include "string_traits.h" -#include "build_info.h" +//#include "build_info.h" //enhancements for @@ -22,13 +23,13 @@ namespace zen { //erase selected elements from any container: template -void erase_if(std::vector& v, Predicate p); +void eraseIf(std::vector& v, Predicate p); template -void erase_if(std::set& s, Predicate p); +void eraseIf(std::set& s, Predicate p); template -void erase_if(std::map& m, Predicate p); +void eraseIf(std::map& m, Predicate p); //append STL containers template @@ -48,14 +49,14 @@ void removeDuplicates(std::vector& v, CompLess less); //binary search returning an iterator template -Iterator binary_search(Iterator first, Iterator last, const T& value, CompLess less); +Iterator binarySearch(Iterator first, Iterator last, const T& value, CompLess less); template -BidirectionalIterator find_last(BidirectionalIterator first, BidirectionalIterator last, const T& value); +BidirectionalIterator findLast(BidirectionalIterator first, BidirectionalIterator last, const T& value); //replacement for std::find_end taking advantage of bidirectional iterators (and giving the algorithm a reasonable name) template -BidirectionalIterator1 search_last(BidirectionalIterator1 first1, BidirectionalIterator1 last1, +BidirectionalIterator1 searchLast(BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2); template Num hashBytes (ByteIterator first, ByteIterator last); @@ -74,17 +75,49 @@ struct StringHash }; -//why, oh wy is there no std::optional::get()??? +//why, oh why is there no std::optional::get()??? template inline T* get( std::optional& opt) { return opt ? &*opt : nullptr; } template inline const T* get(const std::optional& opt) { return opt ? &*opt : nullptr; } +//=========================================================================== +template class SharedRef; +template SharedRef makeSharedRef(Args&& ... args); + +template +class SharedRef //why is there no std::shared_ref??? +{ +public: + SharedRef() = delete; //no suprise memory allocations => always construct with makeSharedRef() + + template + SharedRef(const SharedRef& other) : ref_(other.ref_) {} + + /**/ T& ref() { return *ref_; }; + const T& ref() const { return *ref_; }; + + std::shared_ptr ptr() { return ref_; }; + +private: + explicit SharedRef(std::shared_ptr&& ptr) : ref_(std::move(ptr)) { assert(ref_); } + + template friend SharedRef makeSharedRef(Args&& ... args); + template friend class SharedRef; + + std::shared_ptr ref_; //always bound +}; + +template inline +SharedRef makeSharedRef(Args&&... args) { return SharedRef(std::make_shared(std::forward(args)...)); } +//=========================================================================== + + //######################## implementation ######################## template inline -void erase_if(std::vector& v, Predicate p) +void eraseIf(std::vector& v, Predicate p) { v.erase(std::remove_if(v.begin(), v.end(), p), v.end()); } @@ -93,7 +126,7 @@ void erase_if(std::vector& v, Predicate p) namespace impl { template inline -void set_or_map_erase_if(S& s, Predicate p) +void setOrMapEraseIf(S& s, Predicate p) { for (auto it = s.begin(); it != s.end();) if (p(*it)) @@ -105,11 +138,11 @@ void set_or_map_erase_if(S& s, Predicate p) template inline -void erase_if(std::set& s, Predicate p) { impl::set_or_map_erase_if(s, p); } //don't make this any more generic! e.g. must not compile for std::vector!!! +void eraseIf(std::set& s, Predicate p) { impl::setOrMapEraseIf(s, p); } //don't make this any more generic! e.g. must not compile for std::vector!!! template inline -void erase_if(std::map& m, Predicate p) { impl::set_or_map_erase_if(m, p); } +void eraseIf(std::map& m, Predicate p) { impl::setOrMapEraseIf(m, p); } template inline @@ -147,7 +180,7 @@ void removeDuplicates(std::vector& v) template inline -Iterator binary_search(Iterator first, Iterator last, const T& value, CompLess less) +Iterator binarySearch(Iterator first, Iterator last, const T& value, CompLess less) { static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); @@ -160,7 +193,7 @@ Iterator binary_search(Iterator first, Iterator last, const T& value, CompLess l template inline -BidirectionalIterator find_last(const BidirectionalIterator first, const BidirectionalIterator last, const T& value) +BidirectionalIterator findLast(const BidirectionalIterator first, const BidirectionalIterator last, const T& value) { for (BidirectionalIterator it = last; it != first;) //reverse iteration: 1. check 2. decrement 3. evaluate { @@ -174,7 +207,7 @@ BidirectionalIterator find_last(const BidirectionalIterator first, const Bidirec template inline -BidirectionalIterator1 search_last(const BidirectionalIterator1 first1, BidirectionalIterator1 last1, +BidirectionalIterator1 searchLast(const BidirectionalIterator1 first1, BidirectionalIterator1 last1, const BidirectionalIterator2 first2, const BidirectionalIterator2 last2) { const BidirectionalIterator1 itNotFound = last1; -- cgit