Newer
Older
*
* Created on: Jul 2, 2016
* Author: Jan Travnicek
*/
#ifndef __TREE_HPP_
#define __TREE_HPP_
namespace std {
const tree * getParent ( ) const {
return parent;
}
std::vector < tree > & getChildren ( ) {
return children;
}
const std::vector < tree > & getChildren ( ) const {
return children;
}
void nicePrint ( std::ostream & os, const std::string & prefix, const bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
nextPrefix += " ";
} else {
os << "|-";
nextPrefix += "| ";
for ( unsigned int i = 0; i < children.size ( ); ++i ) {
os << nextPrefix << "|" << std::endl;
children[i].nicePrint ( os, nextPrefix, i == children.size ( ) - 1 );
typedef typename std::vector < tree >::const_iterator const_children_iterator;
class const_structure_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
unsigned level;
bool virtual_node;
bool isEnd;
public:
const_structure_iterator ( typename std::vector < tree >::const_iterator node ) : node ( node ), level ( 0 ), virtual_node ( false ), isEnd ( false ) {
}
const_structure_iterator ( const const_structure_iterator & other ) : node ( other.node ), level ( other.level ), virtual_node ( other.virtual_node ) {
}
const_structure_iterator & operator ++( ) {
if ( virtual_node ) {
const tree * parent = node->getParent ( );
++node;
if ( parent != nullptr ) {
if ( node == parent->getChildren ( ).end ( ) ) {
--level;
node = typename std::vector < tree >::const_iterator ( parent );
} else {
virtual_node = false;
}
} else {
virtual_node = false;
isEnd = true;
}
} else {
typename std::vector < tree >::const_iterator newIter = node->getChildren ( ).begin ( );
if ( newIter != node->getChildren ( ).end ( ) ) {
++level;
node = newIter;
} else {
virtual_node = true;
}
}
return * this;
}
const_structure_iterator operator ++( int ) {
const_structure_iterator tmp ( * this );
operator ++( );
return tmp;
}
const_structure_iterator & operator --( ) {
if ( isEnd ) {
--node;
virtual_node = true;
isEnd = false;
} else if ( virtual_node ) {
typename std::vector < tree >::const_iterator newIter = node->getChildren ( ).end ( );
if ( newIter != node->getChildren ( ).begin ( ) ) {
++level;
node = newIter;
--node;
} else {
virtual_node = false;
}
} else {
if ( parent != nullptr ) {
if ( node == parent->getChildren ( ).begin ( ) ) {
--level;
node = typename std::vector < tree >::const_iterator ( parent );
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
} else {
--node;
virtual_node = true;
}
}
}
return * this;
}
const_structure_iterator operator --( int ) {
const_structure_iterator tmp ( * this );
operator --( );
return tmp;
}
bool operator ==( const const_structure_iterator & other ) {
return node == other.node && virtual_node == other.virtual_node;
}
bool operator !=( const const_structure_iterator & other ) {
return !( * this == other );
}
const T & operator *( ) const {
return node->getData ( );
}
const T * operator ->( ) const {
return & node->getData ( );
}
unsigned getLevel ( ) const {
return level;
}
bool getVirtual ( ) const {
return virtual_node;
}
friend class tree;
};
class const_prefix_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
const_structure_iterator node;
public:
const_prefix_iterator ( typename std::vector < tree >::const_iterator node ) : node ( node ) {
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
}
const_prefix_iterator ( const const_prefix_iterator & other ) : node ( other.node ) {
}
const_prefix_iterator & operator ++( ) {
while ( ( ++node ).getVirtual ( ) );
return * this;
}
const_prefix_iterator operator ++( int ) {
const_prefix_iterator tmp ( * this );
operator ++( );
return tmp;
}
const_prefix_iterator & operator --( ) {
while ( ( --node ).getVirtual ( ) );
return * this;
}
const_prefix_iterator operator --( int ) {
const_prefix_iterator tmp ( * this );
operator --( );
return tmp;
}
bool operator ==( const const_prefix_iterator & other ) {
return node == other.node;
}
bool operator !=( const const_prefix_iterator & other ) {
return !( * this == other );
}
const T & operator *( ) const {
return * node;
}
const T * operator ->( ) const {
return & node->getData ( );
}
unsigned getLevel ( ) const {
return node.getLevel ( );
}
friend class tree;
};
class const_postfix_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
const_structure_iterator node;
public:
const_postfix_iterator ( typename std::vector < tree >::const_iterator node ) : node ( node ) {
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
}
const_postfix_iterator ( const const_postfix_iterator & other ) : node ( other.node ) {
}
const_postfix_iterator & operator ++( ) {
while ( !( ++node ).getVirtual ( ) && !node.isEnd );
return * this;
}
const_postfix_iterator operator ++( int ) {
const_postfix_iterator tmp ( * this );
operator ++( );
return tmp;
}
const_postfix_iterator & operator --( ) {
while ( !( --node ).getVirtual ( ) );
return * this;
}
const_postfix_iterator operator --( int ) {
const_postfix_iterator tmp ( * this );
operator --( );
return tmp;
}
bool operator ==( const const_postfix_iterator & other ) {
return node == other.node;
}
bool operator !=( const const_postfix_iterator & other ) {
return !( * this == other );
}
const T & operator *( ) const {
return * node;
}
const T * operator ->( ) const {
return & node->getData ( );
}
unsigned getLevel ( ) const {
return node.getLevel ( );
}
friend class tree;
};
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
private:
const_children_iterator insert_helper ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
tree * under_node = const_cast < tree * > ( & * under );
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under_node->getChildren ( ) );
typename std::vector < tree >::iterator iter = children.insert ( position, begin, end );
for ( typename std::vector < tree >::iterator iterCopy = iter; begin != end; ++begin, ++iterCopy )
iterCopy->parent = under_node;
template < typename Iterator >
std::vector < tree > fromIterator ( Iterator begin, Iterator end ) {
std::vector < tree > res;
for ( ; begin != end; ++begin )
res.push_back ( tree ( * begin, { } ) );
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const tree < T > & value ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
typename std::vector < tree >::iterator iter = children.insert ( position, value );
iter->parent = const_cast < tree * > ( & * under );
return iter;
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, tree < T > && value ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
typename std::vector < tree >::iterator iter = children.insert ( position, std::move ( value ) );
iter->parent = const_cast < tree * > ( & * under );
return iter;
}
template < class Iterator >
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, Iterator begin, Iterator end ) {
std::vector < tree > children = fromIterator ( begin, end );
return insert_helper ( under, position, children.cbegin ( ), children.cend ( ) );
}
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
return insert_helper ( under, position, begin, end );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public:
tree ( T && data, std::vector < tree > && children ) : data ( std::move ( data ) ), parent ( nullptr ), children ( std::move ( children ) ) {
for ( tree & child : this->children )
child.parent = this;
tree ( const T & data, const std::vector < tree > & subtrees ) : tree ( T ( data ), std::vector < tree > ( subtrees ) ) {
tree ( const T & data, Types ... subtrees ) : tree ( data, std::vector < tree > { subtrees ... } ) {
}
template < typename Iterator, typename std::enable_if < std::is_iterator < Iterator >::value >::type >
tree ( const T & data, Iterator begin, Iterator end ) : tree ( data, fromIterator ( begin, end ) ) {
}
tree ( const T & data, const_children_iterator begin, const_children_iterator end ) : tree ( data, std::vector < tree > ( begin, end ) ) {
}
tree ( const tree & other ) : data ( other.data ), parent ( other.parent ), children ( other.children ) {
for ( tree & child : children )
child.parent = this;
tree ( tree && other ) noexcept : data ( std::move ( other.data ) ), parent ( other.parent ), children ( std::move ( other.children ) ) {
for ( tree & child : children )
child.parent = this;
tree & operator =( const tree & node ) {
return this->operator =( tree ( node ) );
}
tree & operator =( tree && node ) noexcept {
data = std::move ( node.data );
children = std::move ( node.children );
for ( tree & child : children )
child.parent = this;
return * this;
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_children_iterator root ( ) const {
return typename std::vector < tree >::const_iterator ( this );
}
}
const_children_iterator end ( ) const {
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_prefix_iterator prefix_begin ( ) const {
return typename std::vector < tree >::const_iterator ( this );
}
const_prefix_iterator prefix_end ( ) const {
const_prefix_iterator res ( typename std::vector < tree >::const_iterator ( this + 1 ) );
res.node.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_postfix_iterator postfix_begin ( ) const {
const_postfix_iterator res { typename std::vector < tree >::const_iterator ( this ) };
return res;
}
const_postfix_iterator postfix_end ( ) const {
const_postfix_iterator res ( typename std::vector < tree >::const_iterator ( this + 1 ) );
res.node.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_structure_iterator structure_begin ( ) const {
return typename std::vector < tree >::const_iterator ( this );
}
const_structure_iterator structure_end ( ) const {
const_structure_iterator res ( typename std::vector < tree >::const_iterator ( this + 1 ) );
res.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void push_back ( const_children_iterator under, const T & value ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
children.push_back ( tree ( value, { } ) );
std::prev ( children.end ( ) )->parent = const_cast < tree * > ( & * under );
}
void push_back ( const_children_iterator under, T && value ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
children.push_back ( tree ( std::move ( value ), { } ) );
std::prev ( children.end ( ) )->parent = const_cast < tree * > ( & * under );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_children_iterator erase ( const_children_iterator under, const_children_iterator position ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template < class ... Indexes >
const T & operator ()( Indexes ... indexes ) const {
return this->operator ()( { ( unsigned ) indexes ... } );
const T & operator ()( std::initializer_list < unsigned > indexes ) const {
const tree * node = this;
for ( unsigned index : indexes ) {
node = & node->getChildren ( )[index];
template < class ... Indexes >
T & operator ()( Indexes ... indexes ) {
return this->operator ()( { ( unsigned ) indexes ... } );
}
T & operator ()( std::initializer_list < unsigned > indexes ) {
tree * node = this;
for ( unsigned index : indexes ) {
node = & node->getChildren ( )[index];
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sign &= child.getParent ( ) == & node && checkStructure ( child );
return sign;
}
bool checkStructure ( ) const {
return parent == nullptr && checkStructure ( * this );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
friend void swap ( tree & first, tree & second ) {
swap ( std::move ( first ( ) ), std::move ( second ( ) ) );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
int compare ( const tree & other ) const {
std::compare < typename std::decay < T >::type > comp;
auto iterF = this->prefix_begin ( );
auto iterS = other.prefix_begin ( );
for ( ; iterF != this->prefix_end ( ) || iterS != other.prefix_end ( ); ++iterF, ++iterS ) {
int res = comp ( * iterF, * iterS );
if ( res != 0 ) return res;
}
if ( iterF != this->prefix_end ( ) ) return -1;
if ( iterS != other.prefix_end ( ) ) return 1;
return 0;
}
bool operator ==( const tree & other ) {
return compare ( other ) == 0;
}
bool operator !=( const tree & other ) {
return compare ( other ) != 0;
}
bool operator <( const tree & other ) {
return compare ( other ) < 0;
}
bool operator <=( const tree & other ) {
return compare ( other ) <= 0;
}
bool operator >( const tree & other ) {
return compare ( other ) > 0;
}
bool operator >=( const tree & other ) {
return compare ( other ) >= 0;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
std::ostream & nicePrint ( std::ostream & os ) const {
};
template < class T, class ... Ts >
std::ostream & operator <<( std::ostream & out, const tree < T > & t ) {
out << "[";
unsigned level = 0;
for ( typename tree < T >::const_prefix_iterator iter = t.prefix_begin ( ); iter != t.prefix_end ( ); ) {
while ( iter.getLevel ( ) > level ) {
out << "[";
++level;
}
out << level << * iter;
++iter;
bool printComma = iter.getLevel ( ) == level;
while ( iter.getLevel ( ) < level ) {
out << "]";
--level;
printComma = true;
}
if ( printComma && ( level != 0 ) )
out << ",";
}
out << "]";
return out;
}
template < class T >
struct compare < tree < T > > {
int operator ()( const tree < T > & first, const tree < T > & second ) const {
return first.compare ( second );
}
};
} /* namespace std */
#endif /* __TREE_HPP_ */