arabica/include/XSLT/impl/xslt_precedence.hpp

124 lines
2.8 KiB
C++

#ifndef ARABICA_XSLT_PRECEDENCE_HPP
#define ARABICA_XSLT_PRECEDENCE_HPP
#include <algorithm>
class Precedence
{
public:
static const Precedence& InitialPrecedence()
{
static Precedence initial_(0);
return initial_;
} // Precedence
static const Precedence& FrozenPrecedence()
{
static Precedence frozen_;
return frozen_;
} // Precedence
Precedence() :
precedence_(),
children_(0)
{
//precedence_.push_back(0);
} // Precedence
Precedence(const Precedence& rhs) :
precedence_(rhs.precedence_),
children_(rhs.children_)
{
} // Precedence
private:
Precedence(const std::vector<int> precedence) :
precedence_(precedence),
children_(0)
{
} // Precedence
Precedence(int precedence) :
precedence_(),
children_(0)
{
precedence_.push_back(precedence);
} // Precedence
public:
~Precedence() { }
bool operator==(const Precedence& rhs) const
{
return precedence_ == rhs.precedence_;
} // operator==
Precedence& operator=(const Precedence& rhs)
{
std::vector<int> other(rhs.precedence_);
precedence_.swap(other);
children_ = rhs.children_;
return *this;
} // operator=
bool is_descendant(const Precedence& other) const
{
if(other.precedence_.size() <= precedence_.size())
return false;
for(int i = 0, ie = precedence_.size(); i != ie; ++i)
if(other.precedence_[i] != precedence_[i])
return false;
return true;
} // is_descendant
Precedence next_generation()
{
Precedence next(precedence_);
next.precedence_.push_back(++children_);
return next;
} // nextGeneration
private:
std::vector<int> precedence_;
int children_;
friend bool operator<(const Precedence& lhs, const Precedence& rhs);
friend std::ostream& operator<<(std::ostream& os, const Precedence& prec);
}; // class Precedence
bool operator<(const Precedence& lhs, const Precedence& rhs)
{
if(lhs.precedence_ == rhs.precedence_)
return false;
int len = (std::min)(lhs.precedence_.size(), rhs.precedence_.size());
for(int c = 0; c != len; ++c)
{
if(lhs.precedence_[c] < rhs.precedence_[c])
return true;
if(lhs.precedence_[c] > rhs.precedence_[c])
return false;
}
if(lhs.precedence_.size() < rhs.precedence_.size())
return false;
return true;
} // operator>
bool operator>(const Precedence& lhs, const Precedence& rhs)
{
return !(lhs == rhs) && !(lhs < rhs);
} // operator>
std::ostream& operator<<(std::ostream& os, const Precedence& prec)
{
os << '(' << prec.precedence_[0];
for(size_t i = 1; i != prec.precedence_.size(); ++i)
os << ',' << prec.precedence_[i];
os << ')';
return os;
} // operator<<
#endif