File encoding.hpp¶
File List > backends > cxx > include > zmbt > expr > encoding.hpp
Go to the documentation of this file
#ifndef ZMBT_EXPR_ENCODING_HPP_
#define ZMBT_EXPR_ENCODING_HPP_
#include <algorithm>
#include <list>
#include <ostream>
#include "zmbt/core.hpp"
#include "zmbt/reflect.hpp"
#include "keyword.hpp"
#include "attributes.hpp"
#include "keyword_grammar.hpp"
namespace zmbt {
namespace lang {
struct Encoding
{
using K = Keyword;
using V = boost::json::value;
std::vector<K> keywords;
std::vector<std::size_t> depth;
std::vector<V> data;
static bool is_preproc_token(boost::json::value const& value);
static bool is_link_token(boost::json::value const& value);
Encoding() = default;
explicit Encoding(boost::json::value const& value);
explicit Encoding(boost::json::value && value);
std::size_t size() const;
bool operator==(Encoding const& o) const;
bool operator!=(Encoding const& o) const;
void push_back(K const& k, std::size_t const d, V const& v);
void push_back(K const& k, std::size_t const d, V && v);
void append_to_root(Encoding const& tail);
bool preprocess();
};
class EncodingView {
public:
using K = Keyword;
using V = boost::json::value;
struct ExprRow {
K keyword;
std::size_t depth;
V const* data;
std::size_t index;
};
class Iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = ExprRow;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = ExprRow;
Iterator(K const* k, std::size_t const* d, V const* v, std::size_t index, std::size_t offset)
: k_(k)
, d_(d)
, v_(v)
, i_(index)
, index_offset_(offset)
{
}
reference operator*() const {
return {k_[i_], d_[i_] - d_[0], &v_[i_], i_ + index_offset_};
}
Iterator& operator++() { ++i_; return *this; }
Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
Iterator& operator--() { --i_; return *this; }
Iterator operator--(int) { Iterator tmp = *this; --(*this); return tmp; }
Iterator& operator+=(difference_type n) { i_ += n; return *this; }
Iterator& operator-=(difference_type n) { i_ -= n; return *this; }
reference operator[](difference_type n) const { return *(*this + n); }
Iterator operator+(difference_type n) const { return Iterator{k_, d_, v_, i_ + n, index_offset_}; }
Iterator operator-(difference_type n) const { return Iterator{k_, d_, v_, i_ - n, index_offset_}; }
difference_type operator-(Iterator const& other) const { return i_ - other.i_; }
bool operator==(Iterator const& other) const { return i_ == other.i_; }
bool operator!=(Iterator const& other) const { return !(*this == other); }
bool operator<(Iterator const& other) const { return i_ < other.i_; }
bool operator<=(Iterator const& other) const { return i_ <= other.i_; }
bool operator>(Iterator const& other) const { return i_ > other.i_; }
bool operator>=(Iterator const& other) const { return i_ >= other.i_; }
private:
K const* k_;
std::size_t const* d_;
V const* v_;
std::size_t index_offset_;
std::size_t i_;
};
using iterator = Iterator;
using const_iterator = Iterator;
using reverse_iterator = std::reverse_iterator< iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
const_iterator begin() const { return {keywords_, depth_, data_, 0 , index_offset_}; }
const_iterator end() const { return {keywords_, depth_, data_, size_, index_offset_}; }
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
const_reverse_iterator rbegin() const { return const_reverse_iterator{end()}; }
const_reverse_iterator rend() const { return const_reverse_iterator{begin()}; }
const_reverse_iterator crbegin() const { return rbegin(); }
const_reverse_iterator crend() const { return rend(); }
EncodingView(Encoding&& root) = delete;
EncodingView() = default;
EncodingView(K const* k, std::size_t const* d, V const* v,
std::size_t sz, std::size_t index_offset);
EncodingView(Encoding const& root);
std::size_t size() const;
bool empty() const;
std::size_t index_offset() const;
std::size_t depth_offset() const;
ExprRow front() const;
ExprRow back() const;
ExprRow at(std::size_t i) const;
ExprRow operator[](std::size_t i) const
{
return at(i);
}
bool operator==(EncodingView const& o) const;
bool operator!=(EncodingView const& o) const;
Encoding freeze() const;
EncodingView slice(std::size_t start, std::size_t count) const noexcept;
EncodingView subtree(std::size_t const node) const noexcept;
EncodingView traverse_subtrees(std::size_t const node, std::size_t& next) const noexcept;
std::list<EncodingView> children() const;
std::size_t arity() const;
Keyword head() const noexcept;
std::size_t child_idx(int ord) const noexcept;
EncodingView child(int ord) const noexcept;
bool is_const() const;
bool is_boolean() const;
K const* if_keywords() const { return keywords_; }
std::size_t const* if_depth() const { return depth_; }
V const* if_data() const { return data_; }
private:
K const* keywords_;
std::size_t const* depth_;
V const* data_;
std::size_t size_;
std::size_t index_offset_;
};
} // namespace lang
template<>
struct reflect::custom_serialization<lang::Encoding>
{
static boost::json::value
json_from(lang::Encoding const& enc);
static lang::Encoding
dejsonize(boost::json::value const& v);
};
ZMBT_INJECT_SERIALIZATION
} // namespace zmbt
#endif