1 /* Copyright (c) 1997-2021
2    Ewgenij Gawrilow, Michael Joswig, and the polymake team
3    Technische Universität Berlin, Germany
4    https://polymake.org
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version: http://www.gnu.org/licenses/gpl.txt.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 --------------------------------------------------------------------------------
16 */
17 
18 #pragma once
19 
20 #include "polymake/internal/modified_containers.h"
21 
22 namespace pm {
23 
24 template <typename Top, typename Params=typename Top::manipulator_params,
25           bool is_modified=mtagged_list_extract<Params, OperationTag>::is_specified>
26 class modified_tree_impl
27    : public modified_container_impl<Top, Params> {
28    using base_t = modified_container_impl<Top, Params>;
29 public:
30    using typename base_t::iterator;
31    using typename base_t::const_iterator;
32    using typename base_t::reverse_iterator;
33    using typename base_t::const_reverse_iterator;
34    using tree_type = typename base_t::container::tree_type;
35 protected:
finalize(typename tree_type::iterator && it)36    iterator finalize(typename tree_type::iterator&& it)
37    {
38       return iterator(std::move(it), this->manip_top().get_operation());
39    }
finalize(typename tree_type::const_iterator && it)40    const_iterator finalize(typename tree_type::const_iterator&& it) const
41    {
42       return const_iterator(std::move(it), this->manip_top().get_operation());
43    }
finalize(typename tree_type::reverse_iterator && it)44    reverse_iterator finalize(typename tree_type::reverse_iterator&& it)
45    {
46       return reverse_iterator(std::move(it), this->manip_top().get_operation());
47    }
finalize(typename tree_type::const_reverse_iterator && it)48    const_reverse_iterator finalize(typename tree_type::const_reverse_iterator&& it) const
49    {
50       return const_reverse_iterator(std::move(it), this->manip_top().get_operation());
51    }
52 };
53 
54 template <typename Top, typename Params>
55 class modified_tree_impl<Top, Params, false>
56    : public redirected_container<Top, Params> {
57    using base_t = redirected_container<Top, Params>;
58 public:
59    using typename base_t::iterator;
60    using typename base_t::const_iterator;
61    using typename base_t::reverse_iterator;
62    using typename base_t::const_reverse_iterator;
63 protected:
finalize(iterator && it)64    iterator finalize(iterator&& it) { return std::move(it); }
finalize(const_iterator && it)65    const_iterator finalize(const_iterator&& it) const { return std::move(it); }
finalize(reverse_iterator && it)66    reverse_iterator finalize(reverse_iterator&& it) { return std::move(it); }
finalize(const_reverse_iterator && it)67    const_reverse_iterator finalize(const_reverse_iterator&& it) const { return std::move(it); }
68 };
69 
70 template <typename Top, typename Params=typename Top::manipulator_params>
71 class modified_tree
72    : public modified_tree_impl<Top, Params> {
73    using base_t = modified_tree_impl<Top, Params>;
74 public:
75    using typename base_t::iterator;
76    using typename base_t::const_iterator;
77    using typename base_t::reverse_iterator;
78    using typename base_t::const_reverse_iterator;
79    using tree_type = typename base_t::container::tree_type;
80 
81    template <typename Key>
find(const Key & k)82    iterator find(const Key& k)
83    {
84       return this->finalize(this->manip_top().get_container().find(k));
85    }
86    template <typename Key>
find(const Key & k)87    const_iterator find(const Key& k) const
88    {
89       return this->finalize(this->manip_top().get_container().find(k));
90    }
91    template <typename Key, typename Comparator>
find(const Key & k,const Comparator & comparator)92    iterator find(const Key& k, const Comparator& comparator)
93    {
94       return this->finalize(this->manip_top().get_container().find(k,comparator));
95    }
96    template <typename Key, typename Comparator>
find(const Key & k,const Comparator & comparator)97    const_iterator find(const Key& k, const Comparator& comparator) const
98    {
99       return this->finalize(this->manip_top().get_container().find(k,comparator));
100    }
101 
102    template <typename Key, typename RelOp>
find_nearest(const Key & k,const RelOp & relop)103    iterator find_nearest(const Key& k, const RelOp& relop)
104    {
105       return this->finalize(this->manip_top().get_container().find_nearest(k,relop));
106    }
107    template <typename Key, typename RelOp>
find_nearest(const Key & k,const RelOp & relop)108    const_iterator find_nearest(const Key& k, const RelOp& relop) const
109    {
110       return this->finalize(this->manip_top().get_container().find_nearest(k,relop));
111    }
112    template <typename Key, typename RelOp, typename Comparator>
find_nearest(const Key & k,const RelOp & relop,const Comparator & comparator)113    iterator find_nearest(const Key& k, const RelOp& relop, const Comparator& comparator)
114    {
115       return this->finalize(this->manip_top().get_container().find_nearest(k,relop,comparator));
116    }
117    template <typename Key, typename RelOp, typename Comparator>
find_nearest(const Key & k,const RelOp & relop,const Comparator & comparator)118    const_iterator find_nearest(const Key& k, const RelOp& relop, const Comparator& comparator) const
119    {
120       return this->finalize(this->manip_top().get_container().find_nearest(k,relop,comparator));
121    }
122 
123    template <typename Key>
exists(const Key & k)124    bool exists(const Key& k) const
125    {
126       return this->manip_top().get_container().exists(k);
127    }
128 
129    // synonym for sets
130    template <typename Key>
contains(const Key & k)131    bool contains(const Key& k) const { return exists(k); }
132 
133    // TODO: align the naming with STL as per C++17
134 
135    template <typename... Args>
insert(Args &&...args)136    auto insert(Args&&... args)
137    {
138       return this->finalize(this->manip_top().get_container().insert(std::forward<Args>(args)...));
139    }
140 
141    template <typename... Args>
emplace(Args &&...args)142    auto emplace(Args&&... args)
143    {
144       return this->finalize(this->manip_top().get_container().insert_new(std::forward<Args>(args)...));
145    }
146 
147    template <typename... Args>
erase(Args &&...args)148    void erase(Args&&... args)
149    {
150       this->manip_top().get_container().erase(std::forward<Args>(args)...);
151    }
152 
153    template <typename Key>
toggle(const Key & k)154    iterator toggle(const Key& k)
155    {
156       return this->finalize(this->manip_top().get_container().toggle(k));
157    }
158 
159    template <typename Key>
push_front(const Key & k)160    void push_front(const Key& k)
161    {
162       this->manip_top().get_container().push_front(k);
163    }
164    template <typename Key, typename Data>
push_front(const Key & k,const Data & data)165    void push_front(const Key& k, const Data& data)
166    {
167       this->manip_top().get_container().push_front(k,data);
168    }
169 
170    template <typename Key>
push_back(const Key & k)171    void push_back(const Key& k)
172    {
173       this->manip_top().get_container().push_back(k);
174    }
175    template <typename Key, typename Data>
push_back(const Key & k,const Data & data)176    void push_back(const Key& k, const Data& data)
177    {
178       this->manip_top().get_container().push_back(k,data);
179    }
pop_front()180    void pop_front()
181    {
182       this->manip_top().get_container().pop_front();
183    }
pop_back()184    void pop_back()
185    {
186       this->manip_top().get_container().pop_back();
187    }
188 
tree_form()189    bool tree_form() const
190    {
191       return this->manip_top().get_container().tree_form();
192    }
max_size()193    Int max_size() const
194    {
195       return this->manip_top().get_container().max_size();
196    }
clear()197    void clear()
198    {
199       this->manip_top().get_container().clear();
200    }
201 
202    const typename tree_type::key_comparator_type&
get_comparator()203    get_comparator() const
204    {
205       return this->manip_top().get_container().get_comparator();
206    }
207 };
208 
209 } // end namespace pm
210 
211 
212 // Local Variables:
213 // mode:C++
214 // c-basic-offset:3
215 // indent-tabs-mode:nil
216 // End:
217