#ifndef MKF_ELEMENT_HPP_INCLUDED
#define MKF_ELEMENT_HPP_INCLUDED


#include<cstdint>
#include<cstddef>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<string>
#include<vector>
#include<list>
#include<initializer_list>


#ifndef report
#define report  printf("[report in %s] %d %s\n",__FILE__,__LINE__,__func__);
#endif


enum class
ElementKind
{
  null,
  character,
  identifier,
  group,

};


namespace ElementFlag
{
constexpr int  omittable = 1;
constexpr int     repeat = 2;
}


struct Element;
struct Identifier;
struct Group;
struct Book;
struct Definition;


inline
void
skip_space(const char*&  p)
{
    while(isspace(*p))
    {
      ++p;
    }
}


class
Element
{
  uint32_t  state;

  union{
    void*  ptr;

    int         chr;
    Identifier*  id;
    Group*      grp;
  };

public:
  Element();
  Element(uint32_t  flags, int  chr_);
  Element(uint32_t  flags, const char*  id_);
  Element(uint32_t  flags, Identifier*  id_);
  Element(uint32_t  flags, Group*   grp_);
  Element(const Element&   rhs);
  Element(      Element&&  rhs);
 ~Element();


  Element&  operator=(const Element&   rhs);
  Element&  operator=(      Element&&  rhs);

  void  clear();

  ElementKind  get_kind() const;

  const Identifier&  get_identifier() const;
  const Group&            get_group() const;
  int                 get_character() const;

  bool  test_omittable() const;
  bool  test_repeat() const;

  void  print() const;

};


using ElementList = std::list<Element>;


#endif




