summaryrefslogtreecommitdiff
path: root/ept/debtags/coll/operators.h
diff options
context:
space:
mode:
Diffstat (limited to 'ept/debtags/coll/operators.h')
-rw-r--r--ept/debtags/coll/operators.h201
1 files changed, 201 insertions, 0 deletions
diff --git a/ept/debtags/coll/operators.h b/ept/debtags/coll/operators.h
new file mode 100644
index 0000000..2fecbad
--- /dev/null
+++ b/ept/debtags/coll/operators.h
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+
+#ifndef EPT_DEBTAGS_COLL_OPERATORS_H
+#define EPT_DEBTAGS_COLL_OPERATORS_H
+
+#include <set>
+#include <algorithm>
+
+namespace ept {
+namespace debtags {
+namespace coll {
+namespace operators {
+
+/*
+template< typename S, typename VT > struct IsContainer {
+ typedef S T;
+};
+
+template< typename S >
+typename IsContainer< S, typename S::value_type >::T operator &&( const S &a, const S &b ) {
+ S ret;
+ std::set_intersection( a.begin(), a.end(), b.begin(), b.end(),
+ std::inserter( ret, ret.begin() ) );
+ return ret;
+}
+*/
+
+template< typename T >
+T operator+( const T &i, typename T::difference_type o ) {
+ T r = i;
+ std::advance( r, o );
+ return r;
+}
+
+template< typename T >
+std::set< T > operator &( const std::set< T > &a, const std::set< T > &b ) {
+ std::set< T > ret;
+ std::set_intersection( a.begin(), a.end(), b.begin(), b.end(),
+ std::inserter( ret, ret.begin() ) );
+ return ret;
+}
+
+template< typename T >
+std::set< T > operator &( const std::set< T > &a, const T &b ) {
+ std::set< T > ret;
+ if ( a.find( b ) != a.end() ) {
+ std::set< T > r;
+ r.insert( b );
+ return r;
+ }
+ return std::set< T >();
+}
+
+template< typename T >
+std::set< T > operator |( const std::set< T > &a, const T& item ) {
+ std::set< T > ret = a;
+ ret.insert(item);
+ return ret;
+}
+
+template< typename T >
+std::set< T > operator |( const std::set< T > &a, const std::set< T > &b ) {
+ std::set< T > ret;
+ std::set_union( a.begin(), a.end(), b.begin(), b.end(),
+ std::inserter( ret, ret.begin() ) );
+ return ret;
+}
+
+template< typename T >
+std::set< T > operator -( const std::set< T > &a, const std::set< T > &b ) {
+ std::set< T > ret;
+ std::set_difference( a.begin(), a.end(), b.begin(), b.end(),
+ std::inserter(ret, ret.begin() ) );
+ return ret;
+}
+
+template< typename T >
+std::set< T > operator -( const std::set< T > &a, const T& item ) {
+ std::set< T > ret = a;
+ ret.erase(item);
+ return ret;
+}
+
+template< typename T >
+std::set< T > &operator|=( std::set< T > &a, const T& item )
+{
+ a.insert(item);
+ return a;
+}
+
+// General case
+template< typename T, typename SEQ >
+std::set< T > &operator|=( std::set< T > &a, const SEQ& items )
+{
+ for (typename SEQ::const_iterator i = items.begin();
+ i != items.end(); ++i)
+ a.insert(*i);
+ return a;
+}
+
+// Little optimization in case a is empty
+template< typename T >
+std::set< T > &operator |=( std::set< T > &a, const std::set< T > &b ) {
+ if (a.empty())
+ return a = b;
+
+ for (typename std::set<T>::const_iterator i = b.begin();
+ i != b.end(); ++i)
+ a.insert(*i);
+ return a;
+}
+
+// General case, but assumes that b is sorted
+template< typename T, typename SEQ >
+std::set< T > &operator &=( std::set< T > &a, const SEQ& b ) {
+ // Little optimization: if b is empty, we avoid a run through a
+ if (b.empty())
+ {
+ a.clear();
+ return a;
+ }
+
+ typename std::set<T>::iterator ia = a.begin();
+ typename SEQ::const_iterator ib = b.begin();
+ while (ia != a.end())
+ {
+ if (ib != b.end() && *ib < *ia)
+ {
+ ++ib;
+ }
+ else if (ib == b.end() || *ia != *ib)
+ {
+ typename std::set<T>::iterator tmp = ia;
+ ++ia;
+ a.erase(tmp);
+ }
+ else
+ {
+ ++ia;
+ ++ib;
+ }
+ }
+ return a;
+}
+
+template< typename T >
+std::set< T > &operator-=( std::set< T > &a, const T& item )
+{
+ a.erase(item);
+ return a;
+}
+
+// General case, but works only if b is sorted
+template< typename T, typename SEQ >
+std::set< T > &operator -=( std::set< T > &a, const SEQ& b )
+{
+ typename std::set<T>::iterator ia = a.begin();
+ typename SEQ::const_iterator ib = b.begin();
+ while (ia != a.end() && ib != b.end())
+ {
+ if (*ia == *ib)
+ {
+ typename std::set<T>::iterator tmp = ia;
+ ++ia;
+ ++ib;
+ a.erase(tmp);
+ }
+ else if (*ia < *ib)
+ ++ia;
+ else
+ ++ib;
+ }
+ return a;
+}
+
+template< typename T >
+bool operator<=( const T &a, const std::set< T > &b ) {
+ return b.find( a ) != b.end();
+}
+
+template< typename T >
+bool operator<=( const std::set< T > &a, const std::set< T > &b ) {
+ typename std::set<T>::const_iterator x = a.begin();
+
+ for ( typename std::set<T>::const_iterator y = b.begin(); y != b.end(); ++y )
+ if ( x == a.end() )
+ return true;
+ else if (*x == *y)
+ ++x;
+ else if (*x < *y)
+ return false;
+
+ return x == a.end();
+}
+
+}
+}
+}
+}
+
+#endif