Horizon
pns_itemset.h
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2014 CERN
5  * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef __PNS_ITEMSET_H
23 #define __PNS_ITEMSET_H
24 
25 #include <vector>
26 #include <core/kicad_algo.h>
27 #include "pns_item.h"
28 
29 namespace PNS {
30 
34 class LINE;
35 
36 class ITEM_SET
37 {
38 public:
39  struct ENTRY
40  {
41  ENTRY( ITEM* aItem, bool aOwned = false ) :
42  item( aItem ),
43  owned( aOwned )
44  {}
45 
46  ENTRY( const ENTRY& aOther )
47  {
48  owned = aOther.owned;
49 
50  if( aOther.owned )
51  item = aOther.item->Clone();
52  else
53  item = aOther.item;
54  }
55 
56  ~ENTRY()
57  {
58  if( owned )
59  delete item;
60  }
61 
62  bool operator==( const ENTRY& b ) const
63  {
64  return item == b.item;
65  }
66 
67  bool operator<( const ENTRY& b ) const
68  {
69  return item < b.item;
70  }
71 
72  ENTRY& operator=( const ENTRY& aOther )
73  {
74  owned = aOther.owned;
75 
76  if( aOther.owned )
77  item = aOther.item->Clone();
78  else
79  item = aOther.item;
80 
81  return *this;
82  }
83 
84  operator ITEM* () const
85  {
86  return item;
87  }
88 
89  ITEM *item;
90  bool owned;
91  };
92 
93  typedef std::vector<ENTRY> ENTRIES;
94 
95  ITEM_SET( ITEM* aInitialItem = nullptr, bool aBecomeOwner = false )
96  {
97  if( aInitialItem )
98  m_items.emplace_back( ENTRY( aInitialItem, aBecomeOwner ) );
99  }
100 
101  ITEM_SET( const ITEM_SET& aOther )
102  {
103  m_items = aOther.m_items;
104  }
105 
106  ~ITEM_SET();
107 
108  ITEM_SET& operator=( const ITEM_SET& aOther )
109  {
110  m_items = aOther.m_items;
111  return *this;
112  }
113 
114  int Count( int aKindMask = -1 ) const
115  {
116  int n = 0;
117 
118  if( aKindMask == -1 || aKindMask == ITEM::ANY_T )
119  return static_cast<int>( m_items.size() );
120 
121  for( ITEM* item : m_items )
122  {
123  if( item->Kind() & aKindMask )
124  n++;
125  }
126 
127  return n;
128  }
129 
130  bool Empty() const
131  {
132  return m_items.empty();
133  }
134 
135  ENTRIES& Items() { return m_items; }
136  const ENTRIES& CItems() const { return m_items; }
137 
138  ITEM_SET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
139  ITEM_SET& FilterKinds( int aKindMask, bool aInvert = false );
140  ITEM_SET& FilterNet( int aNet, bool aInvert = false );
141  ITEM_SET& FilterMarker( int aMarker, bool aInvert = false );
142 
143  ITEM_SET& ExcludeLayers( int aStart, int aEnd = -1 )
144  {
145  return FilterLayers( aStart, aEnd, true );
146  }
147 
148  ITEM_SET& ExcludeKinds( int aKindMask )
149  {
150  return FilterKinds( aKindMask, true );
151  }
152 
153  ITEM_SET& ExcludeNet( int aNet )
154  {
155  return FilterNet( aNet, true );
156  }
157 
158  ITEM_SET& ExcludeItem( const ITEM* aItem );
159 
160  int Size() const
161  {
162  return static_cast<int>( m_items.size() );
163  }
164 
165  void Add( const LINE& aLine );
166  void Prepend( const LINE& aLine );
167 
168  ITEM* operator[]( size_t aIndex ) const
169  {
170  return m_items[aIndex].item;
171  }
172 
173  ENTRIES::iterator begin() { return m_items.begin(); }
174  ENTRIES::iterator end() { return m_items.end(); }
175  ENTRIES::const_iterator cbegin() const { return m_items.cbegin(); }
176  ENTRIES::const_iterator cend() const { return m_items.cend(); }
177 
178  void Add( ITEM* aItem, bool aBecomeOwner = false )
179  {
180  m_items.emplace_back( ENTRY( aItem, aBecomeOwner ) );
181  }
182 
183  void Prepend( ITEM* aItem, bool aBecomeOwner = false )
184  {
185  m_items.emplace( m_items.begin(), ENTRY( aItem, aBecomeOwner ) );
186  }
187 
188  void Clear()
189  {
190  m_items.clear();
191  }
192 
193  bool Contains( ITEM* aItem ) const
194  {
195  const ENTRY ent( aItem );
196  return alg::contains( m_items, ent );
197  }
198 
199  void Erase( ITEM* aItem )
200  {
201  ENTRY ent( aItem );
202  ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent );
203 
204  if( f != m_items.end() )
205  m_items.erase( f );
206  }
207 
208  template<class T>
209  T* FindByKind( ITEM::PnsKind kind, int index = 0 )
210  {
211  int n = 0;
212 
213  for( const ITEM* item : m_items )
214  {
215  if( item->OfKind( kind ) )
216  {
217  if( index == n )
218  return static_cast<T*>( item );
219  else
220  n++;
221  }
222  }
223 
224  return nullptr;
225  }
226 
227 private:
228  ENTRIES m_items;
229 };
230 
231 }
232 
233 #endif
Definition: pns_itemset.h:37
Base class for PNS router board items.
Definition: pns_item.h:57
virtual ITEM * Clone() const =0
Return a deep copy of the item.
drop< L, min< find_index< L, T >, size< L > >> find
Return the tail of the list L starting at the first occurrence of T, if any such element exists; the ...
Definition: meta.hpp:2388
Definition: pns_itemset.h:40