Newer
Older
*
* Created on: Jul 2, 2016
* Author: Jan Travnicek
*/
#ifndef __TREE_HPP_
#define __TREE_HPP_
#include "compare.hpp"
#include "iterator.hpp"
#include "tree_base.hpp"
const ext::vector < tree > & getChildren ( ) const {
typedef typename ext::vector < tree >::const_iterator const_children_iterator;
class const_structure_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
typename ext::vector < tree >::const_iterator node;
unsigned level;
bool virtual_node;
bool isEnd;
public:
const_structure_iterator ( typename ext::vector < tree >::const_iterator n ) : node ( n ), level ( 0 ), virtual_node ( false ), isEnd ( false ) {
}
const_structure_iterator & operator ++( ) {
if ( virtual_node ) {
const tree * parent = node->getParent ( );
if ( parent != nullptr ) {
if ( node == parent->getChildren ( ).end ( ) ) {
node = typename ext::vector < tree >::const_iterator ( parent );
} else {
virtual_node = false;
}
} else {
virtual_node = false;
isEnd = true;
}
} else {
typename ext::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 ext::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 ext::vector < tree >::const_iterator ( parent );
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
} 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 ext::vector < tree >::const_iterator n ) : node ( n ) {
176
177
178
179
180
181
182
183
184
185
186
187
188
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
}
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 ext::vector < tree >::const_iterator n ) : node ( n ) {
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
}
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:
ext::vector < tree > fromIterator ( Iterator begin, Iterator end ) {
ext::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 ) {
ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( under->getChildren ( ) );
typename ext::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 ) );
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( under->getChildren ( ) );
typename ext::vector < tree >::iterator iter = children.insert ( position, begin, end );
for ( typename ext::vector < tree >::iterator iterCopy = iter; begin != end; ++begin, ++iterCopy )
iterCopy->m_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 ) {
ext::vector < tree > children = fromIterator ( begin, end );
return insert ( under, position, children.cbegin ( ), children.cend ( ) );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public:
tree ( T && data, ext::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 ext::vector < tree > & subtrees ) : tree ( T ( data ), ext::vector < tree > ( subtrees ) ) {
template < typename ... Types >
tree ( const T & data, Types ... subtrees ) : tree ( data, ext::vector < tree > { subtrees ... } ) {
tree ( T && data, Types ... subtrees ) : tree ( std::move ( data ), ext::vector < tree > { subtrees ... } ) {
template < typename Iterator, typename std::enable_if < ext::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, ext::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;
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
return typename ext::vector < tree >::const_iterator ( this );
const_children_iterator parent ( ) const {
return typename ext::vector < tree >::const_iterator ( this->getParent ( ) );
return m_children.begin ( );
}
const_children_iterator end ( ) const {
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_prefix_iterator prefix_begin ( ) const {
return typename ext::vector < tree >::const_iterator ( this );
}
const_prefix_iterator prefix_end ( ) const {
const_prefix_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );
res.node.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_postfix_iterator postfix_begin ( ) const {
const_postfix_iterator res { typename ext::vector < tree >::const_iterator ( this ) };
return res;
}
const_postfix_iterator postfix_end ( ) const {
const_postfix_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );
res.node.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const_structure_iterator structure_begin ( ) const {
return typename ext::vector < tree >::const_iterator ( this );
}
const_structure_iterator structure_end ( ) const {
const_structure_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );
res.isEnd = true;
return res;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void push_back ( const_children_iterator under, ext::tree < T > && value ) {
ext::vector < tree > & children = const_cast < ext::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 ext::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 ) {
ext::vector < tree > & children = const_cast < ext::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 ( first.m_data, second.m_data );
swap ( first.m_children, second.m_children );
swap ( first.m_parent, second.m_parent );
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int compare ( const tree & other ) const {
static ext::compare < typename std::decay < T >::type > comp;
533
534
535
536
537
538
539
540
541
542
543
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
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 {
private:
void nicePrint ( std::ostream & os, std::string prefix, const bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << getData ( ) << std::endl;
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 );
}
}
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;
}
struct compare < ext::tree < T > > {
int operator ()( const ext::tree < T > & first, const ext::tree < T > & second ) const {
return first.compare ( second );
}
};
std::string to_string ( const ext::tree < T > & value ) {
std::stringstream ss;
ss << value;
return ss.str();
}