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 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 
27 #include "pns_item.h"
28 
29 namespace PNS {
30 
37 class LINE;
38 
39 class ITEM_SET
40 {
41 public:
42  struct ENTRY {
43 
44  ENTRY( ITEM* aItem, bool aOwned = false ) :
45  item( aItem ),
46  owned( aOwned )
47  {}
48 
49  ENTRY( const ENTRY& aOther )
50  {
51  owned = aOther.owned;
52 
53  if( aOther.owned )
54  item = aOther.item->Clone();
55  else
56  item = aOther.item;
57  }
58 
59  ~ENTRY()
60  {
61  if( owned )
62  delete item;
63  }
64 
65  bool operator== ( const ENTRY& b ) const
66  {
67  return item == b.item;
68  }
69 
70  bool operator< ( const ENTRY& b ) const
71  {
72  return item < b.item;
73  }
74 
75  ENTRY& operator= ( const ENTRY& aOther )
76  {
77  owned = aOther.owned;
78 
79  if( aOther.owned )
80  item = aOther.item->Clone();
81  else
82  item = aOther.item;
83 
84  return *this;
85  }
86 
87  operator ITEM* () const
88  {
89  return item;
90  }
91 
92  ITEM *item;
93  bool owned;
94  };
95 
96  typedef std::vector<ENTRY> ENTRIES;
97 
98  ITEM_SET( ITEM* aInitialItem = NULL, bool aBecomeOwner = false )
99  {
100  if( aInitialItem )
101  {
102  m_items.push_back( ENTRY( aInitialItem, aBecomeOwner ) );
103  }
104  }
105 
106  ITEM_SET( const ITEM_SET& aOther )
107  {
108  m_items = aOther.m_items;
109  }
110 
111  ~ITEM_SET();
112 
113  const ITEM_SET& operator=( const ITEM_SET& aOther )
114  {
115  m_items = aOther.m_items;
116  return *this;
117  }
118 
119  int Count( int aKindMask = -1 ) const
120  {
121  int n = 0;
122 
123  for( ITEM* item : m_items )
124  {
125  if( item->Kind() & aKindMask )
126  n++;
127  }
128 
129  return n;
130  }
131 
132  bool Empty() const
133  {
134  return m_items.empty();
135  }
136 
137  ENTRIES& Items() { return m_items; }
138  const ENTRIES& CItems() const { return m_items; }
139 
140  ITEM_SET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
141  ITEM_SET& FilterKinds( int aKindMask, bool aInvert = false );
142  ITEM_SET& FilterNet( int aNet, bool aInvert = false );
143  ITEM_SET& FilterMarker( int aMarker, bool aInvert = false );
144 
145  ITEM_SET& ExcludeLayers( int aStart, int aEnd = -1 )
146  {
147  return FilterLayers( aStart, aEnd, true );
148  }
149 
150  ITEM_SET& ExcludeKinds( int aKindMask )
151  {
152  return FilterKinds( aKindMask, true );
153  }
154 
155  ITEM_SET& ExcludeNet( int aNet )
156  {
157  return FilterNet( aNet, true );
158  }
159 
160  ITEM_SET& ExcludeItem( const ITEM* aItem );
161 
162  int Size() const
163  {
164  return m_items.size();
165  }
166 
167  void Add( const LINE& aLine );
168  void Prepend( const LINE& aLine );
169 
170  ITEM* operator[] ( int index ) const
171  {
172  return m_items[index].item;
173  }
174 
175  void Add( ITEM* aItem, bool aBecomeOwner = false )
176  {
177  m_items.push_back( ENTRY( aItem, aBecomeOwner ) );
178  }
179 
180  void Prepend( ITEM* aItem, bool aBecomeOwner = false )
181  {
182  m_items.insert( m_items.begin(), ENTRY( aItem, aBecomeOwner ) );
183  }
184 
185  void Clear()
186  {
187  m_items.clear();
188  }
189 
190  bool Contains( ITEM* aItem ) const
191  {
192  const ENTRY ent( aItem );
193  return std::find( m_items.begin(), m_items.end(), ent ) != m_items.end();
194  }
195 
196  void Erase( ITEM* aItem )
197  {
198  ENTRY ent( aItem );
199  ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent );
200 
201  if( f != m_items.end() )
202  m_items.erase( f );
203  }
204 
205  template<class T>
206  T* FindByKind( ITEM::PnsKind kind, int index = 0 )
207  {
208  int n = 0;
209 
210  for( const ITEM* item : m_items )
211  {
212  if( item->OfKind( kind ) )
213  {
214  if( index == n )
215  return static_cast<T*>( item );
216  else
217  n++;
218  }
219  }
220 
221  return NULL;
222  }
223 
224 private:
225 
226  ENTRIES m_items;
227 };
228 
229 }
230 
231 #endif
Class ITEM.
Definition: pns_item.h:54
virtual ITEM * Clone() const =0
Function Clone()
Definition: pns_itemset.h:39
Definition: pns_line.h:60
PnsKind
Supported item types
Definition: pns_item.h:60
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:131
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:121
Definition: pns_algo_base.cpp:26
Definition: pns_itemset.h:42