cppx-core
Set_.hpp
Go to the documentation of this file.
1 #pragma once // Source encoding: UTF-8 with BOM (π is a lowercase Greek "pi").
2 
3 #include <cppx-core/collections/Range_.hpp> // cppx::Range_
4 #include <cppx-core/language/syntax/macro-define_tag.hpp> // CPPX_DEFINE_TAG
5 #include <cppx-core/language/types/Truth.hpp> // cppx::Truth
6 
7 #include <initializer_list> // std::initializer_list
8 #include <utility> // std::move
9 #include <unordered_set> // std::unordered_set
10 
11 CPPX_DEFINE_TAG( Iterators ); // tag::Iterators
12 CPPX_DEFINE_TAG( Values ); // tag.:Values
13 namespace cppx
14 {
16  initializer_list, move, unordered_set
17  );
18 
19  template< class Key >
20  class Set_
21  : public unordered_set<Key>
22  {
23  using Base = unordered_set<Key>;
24 
25  public:
26  Set_() {}
27 
28  Set_( const Base& other ):
29  Base( other )
30  {}
31 
32  Set_( Base&& other ):
33  Base( move( other ) )
34  {}
35 
36  Set_( const Key& a_key ):
37  Base( &a_key, &a_key + 1 )
38  {}
39 
40  // Only meaningful for integer-like Key:
41  template< class Integer >
42  Set_( const Range_<Integer> range ):
43  Base( range.begin(), range.end() )
44  {}
45 
46  Set_( tag::Values, initializer_list<Key> values ):
47  Base( move( values ) )
48  {}
49 
50  template< class Input_iterator >
51  Set_( tag::Iterators, const Input_iterator first, const Input_iterator beyond ):
52  Base( first, beyond )
53  {}
54  };
55 
56  template< class Key, class Arg >
57  auto is_in( const unordered_set<Key>& set, const Arg& v )
58  -> Truth
59  { return set.count( v ) > 0; }
60 
61 
62  //------------------------------------- Explicit conversions to set:
63 
64  template< class Key >
65  inline auto as_set( const Key& a_key )
66  -> Set_<Key>
67  { return { a_key }; }
68 
69  template< class Integer >
70  inline auto as_set( const Range_<Integer> range )
71  -> Set_<Integer>
72  { return { range }; }
73 
74  template< class Key >
75  inline auto as_set( const initializer_list<Key>& values )
76  -> Set_<Key>
77  { return { values }; }
78 
79 
80  //------------------------------------- Math-like set operations:
81 
82  template< class Key >
83  auto set_union( const unordered_set<Key>& a, const unordered_set<Key>& b )
84  -> Set_<Key>
85  {
86  const unordered_set<Key>& smallest = (a.size() < b.size()? a : b);
87  const unordered_set<Key>& largest = (a.size() < b.size()? b : a);
88 
89  Set_<Key> result = largest;
90  for( const Key& key : smallest )
91  {
92  result.insert( key );
93  }
94  return result;
95  }
96 
97  template< class Key, class Arg >
98  auto set_union( const unordered_set<Key>& a, const Arg& b )
99  -> Set_<Key>
100  { return set_union( a, Set_<Key>( b ) ); }
101 
102  template< class Key, class Arg >
103  auto set_union( const Arg& a, const unordered_set<Key>& b )
104  -> Set_<Key>
105  { return set_union( Set_<Key>( a ), b ); }
106 
107  template< class Key >
108  auto set_difference( const unordered_set<Key>& a, const unordered_set<Key>& b )
109  -> Set_<Key>
110  {
111  Set_<Key> result = a;
112  for( const Key& key : b )
113  {
114  result.erase( key );
115  }
116  return result;
117  }
118 
119  template< class Key, class Arg >
120  auto set_difference( const unordered_set<Key>& a, const Arg& b )
121  -> Set_<Key>
122  { return set_difference( a, Set_<Key>( b ) ); }
123 
124  template< class Key >
125  auto set_intersection( const unordered_set<Key>& a, const unordered_set<Key>& b )
126  -> Set_<Key>
127  {
128  const unordered_set<Key>& smallest = (a.size() < b.size()? a : b);
129  const unordered_set<Key>& largest = (a.size() < b.size()? b : a);
130 
131  Set_<Key> result;
132  for( const Key& key : smallest )
133  {
134  if( is_in( largest, key ) )
135  {
136  result.insert( key );
137  }
138  }
139  return result;
140  }
141 
142 
143  //------------------------------------- Efficiency for temporaries
144 
145  template< class Key >
146  auto set_difference( Set_<Key>&& a, const unordered_set<Key>& b )
147  -> Set_<Key>&&
148  {
149  for( const Key& key : b )
150  {
151  a.erase( key );
152  }
153  return move( a );
154  }
155 
156 } // namespace cppx
Set_(tag::Values, initializer_list< Key > values)
Definition: Set_.hpp:46
Set_(const Key &a_key)
Definition: Set_.hpp:36
Set_(tag::Iterators, const Input_iterator first, const Input_iterator beyond)
Definition: Set_.hpp:51
auto set_difference(const unordered_set< Key > &a, const unordered_set< Key > &b) -> Set_< Key >
Definition: Set_.hpp:108
A drop-in replacement for bool without implicit conversion from/to types other than bool.
Definition: Truth.hpp:34
auto as_set(const Key &a_key) -> Set_< Key >
Definition: Set_.hpp:65
auto is_in(const basic_string_view< Char > &sv, const Char ch) noexcept -> Truth
Definition: is_in.hpp:21
Set_()
Definition: Set_.hpp:26
Set_(const Range_< Integer > range)
Definition: Set_.hpp:42
Truth is a drop-in replacement for bool without implicit conversion from/to types other than bool.
CPPX_USE_STD(basic_string, basic_string_view, bitset, char_traits, size)
$define_tag(NAME) defines NAME as a ~unique pointer type in namespace tag.
Set_(const Base &other)
Definition: Set_.hpp:28
auto set_intersection(const unordered_set< Key > &a, const unordered_set< Key > &b) -> Set_< Key >
Definition: Set_.hpp:125
CPPX_DEFINE_TAG(Iterators)
Set_(Base &&other)
Definition: Set_.hpp:32
auto set_union(const unordered_set< Key > &a, const unordered_set< Key > &b) -> Set_< Key >
Definition: Set_.hpp:83