Newer
Older
*
* Created on: Jul 2, 2016
* Author: Jan Travnicek
*/
#ifndef __TREE_HPP_
#define __TREE_HPP_
namespace std {
tree * m_parent;
std::vector < tree > m_children;
const std::vector < tree > & getChildren ( ) const {
void nicePrint ( std::ostream & os, std::string prefix, const bool last ) const {
for ( unsigned int i = 0; i < m_children.size ( ); ++i ) {
os << prefix << "|" << std::endl;
m_children[i].nicePrint ( os, prefix, i == m_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 n ) : node ( n ), 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 ( );
if ( parent != nullptr ) {
if ( node == parent->getChildren ( ).end ( ) ) {
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 {
const tree * parent = node->getParent ( );
if ( parent != nullptr ) {
if ( node == parent->getChildren ( ).begin ( ) ) {
node = typename std::vector < tree >::const_iterator ( parent );
139
140
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
} 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 n ) : node ( n ) {
189
190
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
}
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 n ) : node ( n ) {
249
250
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
}
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->m_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, 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->m_parent = const_cast < tree * > ( & * under );
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const tree < T > & value ) {
return insert ( under, position, tree < T > ( value ) );
}
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 ) : m_data ( std::move ( data ) ), m_parent ( nullptr ), m_children ( std::move ( children ) ) {
for ( tree & child : m_children )
child.m_parent = this;
}
tree ( const T & data, const std::vector < tree > & subtrees ) : tree ( T ( data ), std::vector < tree > ( subtrees ) ) {
template < typename ... Types >
tree ( const T & data, Types ... subtrees ) : tree ( data, std::vector < tree > { subtrees ... } ) {
tree ( T && data, Types ... subtrees ) : tree ( std::move ( 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 ) : m_data ( other.m_data ), m_parent ( other.m_parent ), m_children ( other.m_children ) {
for ( tree & child : m_children )
child.m_parent = this;
tree ( tree && other ) noexcept : m_data ( std::move ( other.m_data ) ), m_parent ( other.m_parent ), m_children ( std::move ( other.m_children ) ) {
for ( tree & child : m_children )
child.m_parent = this;
tree & operator =( const tree & node ) {
return this->operator =( tree ( node ) );
}
tree & operator =( tree && node ) noexcept {
m_data = std::move ( node.m_data );
m_children = std::move ( node.m_children );
for ( tree & child : m_children )
child.m_parent = this;
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_children_iterator root ( ) const {
return typename std::vector < tree >::const_iterator ( this );
}
const_children_iterator parent ( ) const {
return typename std::vector < tree >::const_iterator ( this->getParent ( ) );
}
return m_children.begin ( );
}
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, std::tree < T > && value ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
children.push_back ( std::move ( value ) );
children.back ( ).m_parent = const_cast < tree * > ( & * under );
}
void push_back ( const_children_iterator under, const std::tree < T > & value ) {
push_back ( under, tree ( value ) );
}
void push_back ( const_children_iterator under, T && value ) {
push_back ( under, tree ( std::move ( value ) ) );
}
void push_back ( const_children_iterator under, const T & value ) {
push_back ( under, T ( value ) );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_children_iterator erase ( const_children_iterator under, const_children_iterator position ) {
std::vector < tree > & children = const_cast < std::vector < tree > & > ( under->getChildren ( ) );
return children.erase ( position );
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 m_parent == nullptr && checkStructure ( * this );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
friend void swap ( tree & first, tree & second ) {
swap ( std::move ( first.m_data ), std::move ( second.m_data ) );
swap ( std::move ( first.m_children ), std::move ( second.m_children ) );
swap ( std::move ( first.m_parent ), std::move ( second.m_parent ) );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int compare ( const tree & other ) const {
static std::compare < typename std::decay < T >::type > comp;
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
586
587
588
589
590
591
592
593
594
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 {
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 );
}
};
template < class T >
string to_string ( const std::tree < T > & value ) {
std::stringstream ss;
ss << value;
return ss.str();
}
} /* namespace std */
#endif /* __TREE_HPP_ */