KiCad PCB EDA Suite
Loading...
Searching...
No Matches
layer_range.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <layer_ids.h>
21
22#ifndef LAYER_RANGE_H
23#define LAYER_RANGE_H
24
25
27{
28private:
32
34 {
35 private:
37 int m_stop;
40
41 int next_layer( int aLayer )
42 {
43 if( m_reverse )
44 {
45 if( aLayer == B_Cu )
46 aLayer = m_layer_count == 2 ? F_Cu :
47 static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2;
48 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
49 aLayer = UNDEFINED_LAYER;
50 else if( aLayer == In1_Cu )
51 aLayer = F_Cu;
52 else
53 aLayer = static_cast<int>( aLayer ) - 2;
54 }
55 else
56 {
57 if( aLayer == F_Cu && m_layer_count == 2 )
58 aLayer = B_Cu;
59 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
60 aLayer = UNDEFINED_LAYER;
61 else if( aLayer == static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2)
62 aLayer = B_Cu;
63 else if( aLayer == F_Cu )
64 aLayer = In1_Cu;
65 else
66 aLayer = static_cast<int>( aLayer ) + 2;
67 }
68
69 return aLayer;
70 }
71
72 public:
73 using iterator_category = std::bidirectional_iterator_tag;
75 using difference_type = std::ptrdiff_t;
78
79 LAYER_RANGE_ITERATOR( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
80 m_current( start ), m_stop( stop ), m_layer_count( layer_count )
81 {
82 if( start & 1 || stop & 1 )
83 throw std::invalid_argument( "Only works for copper layers" );
84
86
87 if( stop == B_Cu || m_stop >= m_current )
88 m_reverse = false;
89 else
90 m_reverse = true;
91 }
92
93 PCB_LAYER_ID operator*() const { return static_cast<PCB_LAYER_ID>( m_current ); }
94
96 {
98 return *this;
99 }
100
102 {
103 LAYER_RANGE_ITERATOR tmp = *this;
104 ++( *this );
105 return tmp;
106 }
107
108 bool operator==( const LAYER_RANGE_ITERATOR& other ) const
109 {
110 return m_current == other.m_current;
111 }
112
113 bool operator!=( const LAYER_RANGE_ITERATOR& other ) const { return !( *this == other ); }
114 };
115
116public:
117 LAYER_RANGE( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
118 m_start( start ), m_stop( stop ), m_layer_count( layer_count )
119 {
120 if( start & 1 || stop & 1 )
121 throw std::invalid_argument( "Only works for copper layers" );
122 }
123
125 m_layer_count ); }
126
128 {
130 return ++it;
131 }
132
133 static bool Contains( int aStart_layer, int aEnd_layer, int aTest_layer )
134 {
135 // B_Cu is the lowest copper layer for Z order copper layers
136 // F_cu = top, B_Cu = bottom
137 // So set the distance from top for B_Cu to INT_MAX
138 if( aTest_layer == B_Cu )
139 aTest_layer = INT_MAX;
140
141 if( aStart_layer == B_Cu )
142 aStart_layer = INT_MAX;
143
144 if( aEnd_layer == B_Cu )
145 aEnd_layer = INT_MAX;
146
147 if( aStart_layer > aEnd_layer )
148 std::swap( aStart_layer, aEnd_layer );
149
150 return aTest_layer >= aStart_layer && aTest_layer <= aEnd_layer;
151 }
152
153 bool Contains( int aTest_layer )
154 {
155 return Contains( m_start, m_stop, aTest_layer );
156 }
157
158 size_t size() const
159 {
160 if( m_start == B_Cu )
161 return m_layer_count;
162 else
163 return ( m_stop - m_start ) / 2 + 1;
164 }
165};
166
167#endif // LAYER_RANGE_H
PCB_LAYER_ID operator*() const
Definition: layer_range.h:93
bool operator==(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:108
LAYER_RANGE_ITERATOR operator++(int)
Definition: layer_range.h:101
bool operator!=(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:113
LAYER_RANGE_ITERATOR & operator++()
Definition: layer_range.h:95
std::bidirectional_iterator_tag iterator_category
Definition: layer_range.h:73
LAYER_RANGE_ITERATOR(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition: layer_range.h:79
int m_layer_count
Definition: layer_range.h:31
PCB_LAYER_ID m_stop
Definition: layer_range.h:30
static bool Contains(int aStart_layer, int aEnd_layer, int aTest_layer)
Definition: layer_range.h:133
LAYER_RANGE_ITERATOR end() const
Definition: layer_range.h:127
size_t size() const
Definition: layer_range.h:158
LAYER_RANGE_ITERATOR begin() const
Definition: layer_range.h:124
PCB_LAYER_ID m_start
Definition: layer_range.h:29
LAYER_RANGE(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition: layer_range.h:117
bool Contains(int aTest_layer)
Definition: layer_range.h:153
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:65
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ In1_Cu
Definition: layer_ids.h:66
@ F_Cu
Definition: layer_ids.h:64