Skip to content
Snippets Groups Projects
Commit b1b3534d authored by Jan Trávníček's avatar Jan Trávníček
Browse files

attempt to fix strict aliasing error

parent f8338b42
No related branches found
No related tags found
No related merge requests found
Pipeline #
......@@ -72,25 +72,40 @@ public:
 
template < class Data, int arity, class ConstData = Data, class Cast = Data >
class AnyaryNode {
typename TupleBuilder < Data, arity >::type children;
typedef typename TupleBuilder < Data, arity >::type ChildrenType;
typedef typename TupleBuilder < ConstData, arity >::type ConstChildrenType;
union ChildrenUnion {
ChildrenType children;
ConstChildrenType const_children;
ChildrenUnion ( ) : children ( ) { }
ChildrenUnion ( ChildrenType data ) : children ( std::move ( data ) ) { }
~ChildrenUnion ( ) {
children.~ChildrenType();
}
};
ChildrenUnion children_union;
 
template < std::size_t ... Indices >
void setParent ( std::index_sequence < Indices ... > ) {
( void ) std::initializer_list < void * > { std::get < Indices > ( children )->parent = static_cast < Cast * > ( this ) ... };
( void ) std::initializer_list < void * > { std::get < Indices > ( children_union.children )->parent = static_cast < Cast * > ( this ) ... };
}
 
public:
AnyaryNode ( typename TupleBuilder < Data, arity >::type c ) : children ( std::move ( c ) ) {
AnyaryNode ( typename TupleBuilder < Data, arity >::type c ) : children_union ( std::move ( c ) ) {
setParent ( std::make_index_sequence < arity > ( ) );
}
 
virtual ~AnyaryNode ( ) noexcept {
}
 
AnyaryNode ( const AnyaryNode & other ) : AnyaryNode ( other.children ) {
AnyaryNode ( const AnyaryNode & other ) : AnyaryNode ( other.children_union.children ) {
}
 
AnyaryNode ( AnyaryNode && other ) noexcept : AnyaryNode ( std::move ( other.children ) ) {
AnyaryNode ( AnyaryNode && other ) noexcept : AnyaryNode ( std::move ( other.children_union.children ) ) {
}
 
AnyaryNode & operator =( const AnyaryNode & other ) {
......@@ -98,7 +113,7 @@ public:
}
 
AnyaryNode & operator =( AnyaryNode && other ) noexcept {
std::swap ( this->children, other.children );
std::swap ( this->children_union.children, other.children_union.children );
 
setParent ( std::make_index_sequence < arity > ( ) );
 
......@@ -106,32 +121,32 @@ public:
}
 
const typename TupleBuilder < Data, arity >::type & getElements ( ) {
return children;
return children_union.children;
}
 
const typename TupleBuilder < ConstData, arity >::type & getElements ( ) const {
return reinterpret_cast < const typename TupleBuilder < ConstData, arity >::type & > ( children );
return children_union.const_children;
}
 
template < int N >
const ConstData & getElement ( ) const {
return reinterpret_cast < const ConstData & > ( std::get < N > ( children ) );
return std::get < N > ( children_union.const_children );
}
 
template < int N >
Data & getElement ( ) {
return std::get < N > ( children );
return std::get < N > ( children_union.children );
}
 
void setElements ( typename TupleBuilder < Data, arity >::type c ) {
children = std::move ( c );
children_union.children = std::move ( c );
setParent ( std::make_index_sequence < arity > ( ) );
}
 
template < int N >
void setElement ( Data d ) {
std::get < N > ( children ) = std::move ( d );
std::get < N > ( children )->parent = static_cast < Cast * > ( this );
std::get < N > ( children_union.children ) = std::move ( d );
std::get < N > ( children_union.children )->parent = static_cast < Cast * > ( this );
}
 
};
......@@ -242,7 +257,19 @@ public:
 
template < class Data, class ConstData = Data, class Cast = Data >
class FixedaryNode {
std::vector < Data > children;
union ChildrenUnion {
std::vector < Data > children;
std::vector < ConstData > const_children;
ChildrenUnion ( ) : children ( ) { }
ChildrenUnion ( std::vector < Data > data ) : children ( std::move ( data ) ) { }
~ChildrenUnion ( ) {
children.~vector();
}
};
ChildrenUnion children_union;
 
public:
template < typename ... Types >
......@@ -250,24 +277,24 @@ public:
Data args[] { std::move ( data ) ... };
 
for ( Data & child : args )
children.push_back ( std::move ( child ) );
children_union.children.push_back ( std::move ( child ) );
 
for ( Data & child : children )
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
}
 
FixedaryNode ( std::vector < Data > c ) : children ( std::move ( c ) ) {
for ( Data & child : children )
FixedaryNode ( std::vector < Data > c ) : children_union ( std::move ( c ) ) {
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
}
 
virtual ~FixedaryNode ( ) noexcept {
}
 
FixedaryNode ( const FixedaryNode & other ) : FixedaryNode ( other.children ) {
FixedaryNode ( const FixedaryNode & other ) : FixedaryNode ( other.children_union.children ) {
}
 
FixedaryNode ( FixedaryNode && other ) noexcept : FixedaryNode ( std::move ( other.children ) ) {
FixedaryNode ( FixedaryNode && other ) noexcept : FixedaryNode ( std::move ( other.children_union.children ) ) {
}
 
FixedaryNode & operator =( const FixedaryNode & other ) {
......@@ -275,63 +302,75 @@ public:
}
 
FixedaryNode & operator =( FixedaryNode && other ) noexcept {
std::swap ( this->children, other.children );
std::swap ( this->children_union.children, other.children_union.children );
 
for ( Data & child : children )
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
 
return * this;
}
 
std::vector < Data > & getChildren ( ) {
return children;
return children_union.children;
}
 
const std::vector < ConstData > & getChildren ( ) const {
return reinterpret_cast < const std::vector < ConstData > & > ( children );
return children_union.const_children;
}
 
void setChildren ( std::vector < Data > c ) {
if ( c.size ( ) != children.size ( ) )
if ( c.size ( ) != children_union.children.size ( ) )
throw "Arity != size";
 
children = std::move ( c );
children_union.children = std::move ( c );
 
for ( Data & child : children )
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
}
 
void setChild ( Data d, int index ) {
if ( children.size ( ) >= index )
if ( children_union.children.size ( ) >= index )
throw "Index out of bounds";
 
children[index] = std::move ( d );
children_union.children[index] = std::move ( d );
 
children[index]->parent = static_cast < Cast * > ( this );
children_union.children[index]->parent = static_cast < Cast * > ( this );
}
 
};
 
template < class Data, class ConstData = Data, class Cast = Data >
class VararyNode {
std::vector < Data > children;
union ChildrenUnion {
std::vector < Data > children;
std::vector < ConstData > const_children;
ChildrenUnion ( ) : children ( ) { }
ChildrenUnion ( std::vector < Data > data ) : children ( std::move ( data ) ) { }
~ChildrenUnion ( ) {
children.~vector();
}
};
ChildrenUnion children_union;
 
public:
VararyNode ( ) {
}
 
VararyNode ( std::vector < Data > c ) : children ( std::move ( c ) ) {
for ( Data & child : children )
VararyNode ( std::vector < Data > c ) : children_union ( std::move ( c ) ) {
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
}
 
virtual ~VararyNode ( ) noexcept {
}
 
VararyNode ( const VararyNode & other ) : VararyNode ( other.children ) {
VararyNode ( const VararyNode & other ) : VararyNode ( other.children_union.children ) {
}
 
VararyNode ( VararyNode && other ) noexcept : VararyNode ( std::move ( other.children ) ) {
VararyNode ( VararyNode && other ) noexcept : VararyNode ( std::move ( other.children_union.children ) ) {
}
 
VararyNode & operator =( const VararyNode & other ) {
......@@ -339,33 +378,33 @@ public:
}
 
VararyNode & operator =( VararyNode && other ) noexcept {
std::swap ( this->children, other.children );
std::swap ( this->children_union.children, other.children_union.children );
 
for ( Data & child : children )
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
 
return * this;
}
 
std::vector < Data > & getChildren ( ) {
return children;
return children_union.children;
}
 
const std::vector < ConstData > & getChildren ( ) const {
return reinterpret_cast < const std::vector < ConstData > & > ( children );
return children_union.const_children;
}
 
void setChildren ( std::vector < Data > c ) {
children = std::move ( c );
children_union.children = std::move ( c );
 
for ( Data & child : children )
for ( Data & child : children_union.children )
child->parent = static_cast < Cast * > ( this );
}
 
void setChild ( Data d, int index ) {
children[index] = std::move ( d );
children_union.children[index] = std::move ( d );
 
children[index]->parent = static_cast < Cast * > ( this );
children_union.children[index]->parent = static_cast < Cast * > ( this );
}
 
void setChild ( Data d, typename std::vector < Data >::iterator it ) {
......@@ -375,7 +414,7 @@ public:
}
 
typename std::vector < Data >::iterator insert ( typename std::vector < Data >::iterator it, Data d ) {
it = children.insert ( it, std::move ( d ) );
it = children_union.children.insert ( it, std::move ( d ) );
 
( * std::prev ( it ) )->parent = static_cast < Cast * > ( this );
 
......@@ -384,13 +423,13 @@ public:
 
template < class InputIterator >
typename std::vector < Data >::iterator insert ( typename std::vector < Data >::iterator it, InputIterator first, InputIterator last ) {
size_t off = it - children.begin ( );
size_t off = it - children_union.children.begin ( );
size_t size = last - first;
 
children.insert ( it, first, last );
it = children.begin ( ) + off;
children_union.children.insert ( it, first, last );
it = children_union.children.begin ( ) + off;
 
// TODO on g++-4.9 use: it = children->insert( it, first, last );
// TODO on g++-4.9 use: it = children_union.children.insert( it, first, last );
typename std::vector < Data >::iterator end = it + size;
 
for ( ; it != end; it++ )
......@@ -400,8 +439,8 @@ public:
}
 
void pushBackChild ( Data d ) {
children.push_back ( std::move ( d ) );
children[children.size ( ) - 1]->parent = static_cast < Cast * > ( this );
children_union.children.push_back ( std::move ( d ) );
children_union.children[children_union.children.size ( ) - 1]->parent = static_cast < Cast * > ( this );
}
 
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment