summaryrefslogtreecommitdiff
path: root/tiger-compiler/lib/misc/set.hh
blob: 5ded61b9e68d50379734f4584d0a8b5cb263eb76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
 ** \file misc/set.hh
 ** \brief misc::set: wrapper around std::set.
 **
 ** Set class is a std::set wrapper used to facilitate set
 ** operations such as '+' (union) and '-' and also redefine
 ** functions such as set_union, set_intersection etc. in
 ** order to be more specific and more simple to handle set for our
 ** purpose.
 **/

#pragma once

#include <algorithm>
#include <iosfwd>
#include <set>
#include <vector>
#include <misc/concepts.hh>

namespace misc
{
  template <typename Key,
            typename Compare = std::less<Key>,
            typename Allocator = std::allocator<Key>>
  /**
   ** \brief The class misc::set is wrapper around std::set.
   **
   ** Because Doxygen doesn't handle template
   ** parameters names mix we keep the shorter version,
   ** so K for Key, C for Compare and A for Allocator. */
  class set : public std::set<Key, Compare, Allocator>
  {
  public:
    /// \name typedefs
    /// \{
    using set_type = typename std::set<Key, Compare, Allocator>;

    using iterator = typename set_type::iterator;
    using const_iterator = typename set_type::const_iterator;
    using reverse_iterator = typename set_type::reverse_iterator;
    using const_reverse_iterator = typename set_type::const_reverse_iterator;
    using size_type = typename set_type::size_type;
    using const_reference = typename set_type::const_reference;
    /// \}

    /// \name constructor(s)/destructor.
    /// \{

    explicit set() = default;

    template <typename Iter>
      requires Iterator<Iter, Key>
    explicit set(Iter first, Iter last);

    /* Useful to convert a container (e.g. std::vector) in misc::set.  */
    template <typename Container>
      requires ConstIterableType<Container, Key>
    explicit set(const Container v);

    /// \}

    /** \name Element vs. set.
        \{ */

    /// Is \a k part of \a this set?
    bool has(const Key& k) const;

    /** \brief Return the addition of \a data into \a this.
        \a data must not yet be part of \a this. */
    set operator+(const Key& data) const;

    /** \brief Insert \a data in \a this.
        \a data must not yet be part of \a this. */
    set& operator+=(const Key& data);

    /** \brief Return the removal of \a data into \a this.
        \a data must be part of \a this. */
    set operator-(const Key& data) const;

    /** \brief Remove \a data from \a this.
        \a data must be part of \a this. */
    set& operator-=(const Key& data);

    /// \}

    /** \name Set vs. set.
        \{ */

    /// Union with another set \a s.
    // FIXME: Deprecate this use, it ought to be direct sum.
    set operator+(const set<Key, Compare, Allocator>& s) const;

    /// In place union with another set \a s.
    set& operator+=(const set<Key, Compare, Allocator>& s);

    /// Subtraction with another set \a s.
    set operator-(const set<Key, Compare, Allocator>& s) const;

    /// In place subtraction with another set \a s.
    set& operator-=(const set<Key, Compare, Allocator>& s);

    /// Union with another set \a s.
    set operator|(const set& s) const;

    /// In place union with another set \a s.
    set& operator|=(const set& s);

    /// Intersection with another set \a s.
    set operator&(const set& s) const;

    /// In place intersection with another set \a s.
    set& operator&=(const set& s);

    /// \}
  }; // class set

  template <typename Key, typename Compare, typename Allocator>
  inline set<Key, Compare, Allocator>
  set_difference(const set<Key, Compare, Allocator>& s1,
                 const set<Key, Compare, Allocator>& s2);

  template <typename Key, typename Compare, typename Allocator>
  inline set<Key, Compare, Allocator>
  set_intersection(const set<Key, Compare, Allocator>& s1,
                   const set<Key, Compare, Allocator>& s2);

  template <typename Key, typename Compare, typename Allocator>
  inline set<Key, Compare, Allocator>
  set_union(const set<Key, Compare, Allocator>& s1,
            const set<Key, Compare, Allocator>& s2);

  /* Print a human-dump for debugging.

  Warning: this method requires that type Key overloads the operator
  '<<'.  If it is not the case do it or remove set print method
  and << operator (see below).  */
  template <typename Key, typename Compare, typename Allocator>
  inline std::ostream& operator<<(std::ostream& ostr,
                                  const set<Key, Compare, Allocator>& s);

  template <typename Key, typename Compare, typename Allocator>
  inline bool operator%(const Key& k, const set<Key, Compare, Allocator>& s);

} // namespace misc

#include <misc/set.hxx>