Support for const ranges working
This commit is contained in:
parent
4ab29013ec
commit
512d6b342d
@ -29,6 +29,7 @@ namespace chaiscript
|
|||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct Bidir_Range
|
struct Bidir_Range
|
||||||
{
|
{
|
||||||
|
typedef Container container_type;
|
||||||
typedef typename std::iterator_traits<typename Container::iterator>::reference reference_type;
|
typedef typename std::iterator_traits<typename Container::iterator>::reference reference_type;
|
||||||
|
|
||||||
Bidir_Range(Container &c)
|
Bidir_Range(Container &c)
|
||||||
@ -83,42 +84,92 @@ namespace chaiscript
|
|||||||
typename Container::iterator m_end;
|
typename Container::iterator m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Range>
|
template<typename Container>
|
||||||
struct Retro
|
struct Const_Bidir_Range
|
||||||
{
|
{
|
||||||
Retro(const Range &r)
|
typedef const Container container_type;
|
||||||
: m_r(r)
|
typedef typename std::iterator_traits<typename Container::const_iterator>::reference const_reference_type;
|
||||||
{}
|
|
||||||
|
|
||||||
bool empty() { return m_r.empty(); }
|
Const_Bidir_Range(const Container &c)
|
||||||
void pop_front() { m_r.pop_back(); }
|
: m_begin(c.begin()), m_end(c.end())
|
||||||
void pop_back() { m_r.pop_front(); }
|
{
|
||||||
typename Range::reference_type front() { return m_r.back(); }
|
}
|
||||||
typename Range::reference_type back() { return m_r.front(); }
|
|
||||||
|
|
||||||
private:
|
bool empty() const
|
||||||
Range m_r;
|
{
|
||||||
|
return m_begin == m_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_front()
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
throw std::range_error("Range empty");
|
||||||
|
}
|
||||||
|
++m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back()
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
throw std::range_error("Range empty");
|
||||||
|
}
|
||||||
|
--m_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference_type front() const
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
throw std::range_error("Range empty");
|
||||||
|
}
|
||||||
|
return *m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference_type back() const
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
throw std::range_error("Range empty");
|
||||||
|
}
|
||||||
|
typename Container::const_iterator pos = m_end;
|
||||||
|
--pos;
|
||||||
|
return *(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Container::const_iterator m_begin;
|
||||||
|
typename Container::const_iterator m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
/**
|
/**
|
||||||
* Add Bidir_Range support for the given ContainerType
|
* Add Bidir_Range support for the given ContainerType
|
||||||
*/
|
*/
|
||||||
|
template<typename Bidir_Type>
|
||||||
|
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<Bidir_Type>(), type + "_Range");
|
||||||
|
|
||||||
|
copy_constructor<Bidir_Type>(type + "_Range", m);
|
||||||
|
|
||||||
|
m->add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range");
|
||||||
|
|
||||||
|
m->add(fun(&Bidir_Type::empty), "empty");
|
||||||
|
m->add(fun(&Bidir_Type::pop_front), "pop_front");
|
||||||
|
m->add(fun(&Bidir_Type::front), "front");
|
||||||
|
m->add(fun(&Bidir_Type::pop_back), "pop_back");
|
||||||
|
m->add(fun(&Bidir_Type::back), "back");
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(user_type<Bidir_Range<ContainerType> >(), type + "_Range");
|
detail::input_range_type_impl<Bidir_Range<ContainerType> >(type,m);
|
||||||
|
detail::input_range_type_impl<Const_Bidir_Range<ContainerType> >("Const_" + type, m);
|
||||||
copy_constructor<Bidir_Range<ContainerType> >(type + "_Range", m);
|
|
||||||
|
|
||||||
m->add(constructor<Bidir_Range<ContainerType> (ContainerType &)>(), "range");
|
|
||||||
|
|
||||||
m->add(fun(&Bidir_Range<ContainerType>::empty), "empty");
|
|
||||||
m->add(fun(&Bidir_Range<ContainerType>::pop_front), "pop_front");
|
|
||||||
m->add(fun(&Bidir_Range<ContainerType>::front), "front");
|
|
||||||
m->add(fun(&Bidir_Range<ContainerType>::pop_back), "pop_back");
|
|
||||||
m->add(fun(&Bidir_Range<ContainerType>::back), "back");
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user