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 (C) 2024 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 : static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2;
47 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
48 aLayer = UNDEFINED_LAYER;
49 else if( aLayer == In1_Cu )
50 aLayer = F_Cu;
51 else
52 aLayer = static_cast<int>( aLayer ) - 2;
53 }
54 else
55 {
56 if( aLayer == F_Cu && m_layer_count == 2 )
57 aLayer = B_Cu;
58 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
59 aLayer = UNDEFINED_LAYER;
60 else if( aLayer == static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2)
61 aLayer = B_Cu;
62 else if( aLayer == F_Cu )
63 aLayer = In1_Cu;
64 else
65 aLayer = static_cast<int>( aLayer ) + 2;
66 }
67
68 return aLayer;
69 }
70
71 public:
72 using iterator_category = std::bidirectional_iterator_tag;
74 using difference_type = std::ptrdiff_t;
77
78 LAYER_RANGE_ITERATOR( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
79 m_current( start ), m_stop( stop ), m_layer_count( layer_count )
80 {
81 if( start & 1 || stop & 1 )
82 throw std::invalid_argument( "Only works for copper layers" );
83
85
86 if( stop == B_Cu || m_stop >= m_current )
87 m_reverse = false;
88 else
89 m_reverse = true;
90 }
91
92 PCB_LAYER_ID operator*() const { return static_cast<PCB_LAYER_ID>( m_current ); }
93
95 {
97 return *this;
98 }
99
101 {
102 LAYER_RANGE_ITERATOR tmp = *this;
103 ++( *this );
104 return tmp;
105 }
106
107 bool operator==( const LAYER_RANGE_ITERATOR& other ) const
108 {
109 return m_current == other.m_current;
110 }
111
112 bool operator!=( const LAYER_RANGE_ITERATOR& other ) const { return !( *this == other ); }
113 };
114
115public:
116 LAYER_RANGE( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
117 m_start( start ), m_stop( stop ), m_layer_count( layer_count )
118 {
119 if( start & 1 || stop & 1 )
120 throw std::invalid_argument( "Only works for copper layers" );
121 }
122
125 {
127 return ++it;
128 }
129
130 static bool Contains( int aStart_layer, int aEnd_layer, int aTest_layer )
131 {
132 // B_Cu is the lowest copper layer for Z order copper layers
133 // F_cu = top, B_Cu = bottom
134 // So set the distance from top for B_Cu to INT_MAX
135 if( aTest_layer == B_Cu )
136 aTest_layer = INT_MAX;
137
138 if( aStart_layer == B_Cu )
139 aStart_layer = INT_MAX;
140
141 if( aEnd_layer == B_Cu )
142 aEnd_layer = INT_MAX;
143
144 if( aStart_layer > aEnd_layer )
145 std::swap( aStart_layer, aEnd_layer );
146
147 return aTest_layer >= aStart_layer && aTest_layer <= aEnd_layer;
148 }
149
150 bool Contains( int aTest_layer )
151 {
152 return Contains( m_start, m_stop, aTest_layer );
153 }
154};
155
156#endif // LAYER_RANGE_H
PCB_LAYER_ID operator*() const
Definition: layer_range.h:92
bool operator==(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:107
LAYER_RANGE_ITERATOR operator++(int)
Definition: layer_range.h:100
bool operator!=(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:112
LAYER_RANGE_ITERATOR & operator++()
Definition: layer_range.h:94
std::bidirectional_iterator_tag iterator_category
Definition: layer_range.h:72
LAYER_RANGE_ITERATOR(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition: layer_range.h:78
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:130
LAYER_RANGE_ITERATOR end() const
Definition: layer_range.h:124
LAYER_RANGE_ITERATOR begin() const
Definition: layer_range.h:123
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:116
bool Contains(int aTest_layer)
Definition: layer_range.h:150
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