corelib/include/ebcl/SyntaxTree.hh

120 lines
3.2 KiB
C++
Raw Normal View History

2018-03-31 16:58:13 +02:00
/******************************************************************************/
/* ABSTRACT SYNTAX TREE *******************************************************/
/******************************************************************************/
#ifndef _H_EBCL_SYNTAXTREE
#define _H_EBCL_SYNTAXTREE
#include <ebcl/Types.hh>
#include <ebcl/Arrays.hh>
namespace ebcl {
/*= SYNTAX TREE ==============================================================*/
/*
* A syntax tree has typed nodes; each nodes may have 0, 1 or more children
* of various types. In addition, a node may carry additional data. The type
* of the data associated to a given node is not known.
*
* Nodes are accessed using integer indices. The tree's root node is always at
* index 0.
*/
template<
// Node type (should be an enum)
typename NodeType ,
// Data storage size
size_t InPlaceSize = sizeof( void* )
> class T_SyntaxTree
{
public:
using E_Node = NodeType;
using T_Self = T_SyntaxTree< NodeType , InPlaceSize >;
static constexpr size_t StorageSize
= T_VariantExt< InPlaceSize >::StorageSize;
private:
struct T_Node_
{
// Node type
E_Node type;
// Index of the parent node
uint32_t parent;
// Indices of the node's children
T_AutoArray< uint32_t , 8 > children;
// Extra data storage
T_VariantExt< StorageSize > data;
explicit T_Node_( E_Node type ,
uint32_t parent ) noexcept;
T_Node_( T_Node_ const& ) = delete;
T_Node_& operator =( T_Node_ const& ) = delete;
T_Node_( T_Node_&& other ) noexcept;
T_Node_& operator =( T_Node_&& other ) noexcept;
};
T_Array< T_Node_ > nodes_;
public:
M_TEMPLATE_POINTERS( T_SyntaxTree );
// Create the syntax tree, specifying the type of the root node
explicit T_SyntaxTree( E_Node rootType ) noexcept;
// Copy is disabled
T_SyntaxTree( T_Self const& ) = delete;
T_Self& operator =( T_Self const& other ) = delete;
// Move construction / assignment
T_SyntaxTree( T_Self&& other ) noexcept;
T_Self& operator =( T_Self&& other ) noexcept;
// Swapping
T_Self& swap( T_Self& other ) noexcept;
//----------------------------------------------------------------------
// Get the type of a node
E_Node typeOf( uint32_t node ) const noexcept;
// Returns the index of a node's parent. The root node will always
// return its own index.
uint32_t parentOf( uint32_t node ) const noexcept;
// Access the list of children for a node
T_AutoArray< uint32_t , 8 > const& childrenOf(
uint32_t node ) const noexcept;
// Check whether some node contains data
bool hasData( uint32_t node ) const noexcept;
// Access the data stored inside a node
template< typename D >
D const& dataOf( uint32_t node ) const;
//----------------------------------------------------------------------
// Add a new child, return its index
uint32_t addChild(
uint32_t parent ,
E_Node type ) noexcept;
// Add data to a node
template< typename D , typename ... Args >
D& newData( uint32_t node , Args&& ... args );
// Access the data stored inside a node
template< typename D >
D& dataOf( uint32_t node );
};
template< typename T , size_t S >
void swap( T_SyntaxTree< T , S >& lhs , T_SyntaxTree< T , S >& rhs ) noexcept;
}
#endif // _H_EBCL_SYNTAXTREE
#include <ebcl/inline/SyntaxTree.hh>