HelenOS sources
This source file includes following definitions.
- advance
- distance
- next
- prev
- base
- make_reverse_iterator
- back_inserter
- front_inserter
- inserter
- base
- make_move_iterator
- equal
- failed
- begin
- begin
- end
- end
- begin
- end
- cbegin
- cend
- rbegin
- rbegin
- rend
- rend
- rbegin
- rend
- rbegin
- rend
- crbegin
- crend
- size
- empty
- empty
- empty
- data
- data
- data
- data
#ifndef LIBCPP_BITS_ITERATOR
#define LIBCPP_BITS_ITERATOR
#include <__bits/memory/addressof.hpp>
#include <cstdlib>
#include <initializer_list>
#include <iosfwd>
#include <type_traits>
#include <utility>
namespace std
{
struct input_iterator_tag
{ };
struct output_iterator_tag
{ };
struct forward_iterator_tag: input_iterator_tag
{ };
struct bidirectional_iterator_tag: forward_iterator_tag
{ };
struct random_access_iterator_tag: bidirectional_iterator_tag
{ };
template<class Iterator>
struct iterator_traits
{
using difference_type = typename Iterator::difference_type;
using value_type = typename Iterator::value_type;
using iterator_category = typename Iterator::iterator_category;
using reference = typename Iterator::reference;
using pointer = typename Iterator::pointer;
};
template<class T>
struct iterator_traits<T*>
{
using difference_type = ptrdiff_t;
using value_type = T;
using iterator_category = random_access_iterator_tag;
using reference = T&;
using pointer = T*;
};
template<class T>
struct iterator_traits<const T*>
{
using difference_type = ptrdiff_t;
using value_type = T;
using iterator_category = random_access_iterator_tag;
using reference = const T&;
using pointer = const T*;
};
template<
class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&
>
struct iterator
{
using difference_type = Distance;
using value_type = T;
using iterator_category = Category;
using reference = Reference;
using pointer = Pointer;
};
template<class InputIterator, class Distance>
void advance(InputIterator& it, Distance n)
{
for (Distance i = Distance{}; i < n; ++i)
++it;
}
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
using cat_t = typename iterator_traits<InputIterator>::iterator_category;
using diff_t = typename iterator_traits<InputIterator>::difference_type;
if constexpr (is_same_v<cat_t, random_access_iterator_tag>)
return last - first;
else
{
diff_t diff{};
while (first != last)
{
++diff;
++first;
}
return diff;
}
}
template<class ForwardIterator>
ForwardIterator
next(ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1)
{
advance(it, n);
return it;
}
template<class BidirectionalIterator>
BidirectionalIterator
prev(BidirectionalIterator it,
typename iterator_traits<BidirectionalIterator>::difference_type n = 1)
{
advance(it, -n);
return it;
}
template<class Iterator>
class reverse_iterator
: public iterator<
typename iterator_traits<Iterator>::iterator_category,
typename iterator_traits<Iterator>::value_type,
typename iterator_traits<Iterator>::difference_type,
typename iterator_traits<Iterator>::pointer,
typename iterator_traits<Iterator>::reference
>
{
public:
using iterator_type = Iterator;
using difference_type = typename iterator_traits<Iterator>::difference_type;
using reference = typename iterator_traits<Iterator>::reference;
using pointer = typename iterator_traits<Iterator>::pointer;
reverse_iterator()
: current_{}
{ }
explicit reverse_iterator(Iterator it)
: current_{it}
{ }
template<class U>
reverse_iterator(const reverse_iterator<U>& other)
: current_{other.current_}
{ }
template<class U>
reverse_iterator& operator=(const reverse_iterator<U>& other)
{
current_ = other.base();
return *this;
}
Iterator base() const
{
return current_;
}
reference operator*() const
{
auto tmp = current_;
return *(--tmp);
}
pointer operator->() const
{
return addressof(operator*());
}
reverse_iterator& operator++()
{
--current_;
return *this;
}
reverse_iterator operator++(int)
{
auto tmp = *this;
--current_;
return tmp;
}
reverse_iterator& operator--()
{
++current_;
return *this;
}
reverse_iterator operator--(int)
{
auto tmp = *this;
++current_;
return tmp;
}
reverse_iterator operator+(difference_type n) const
{
return reverse_iterator{current_ - n};
}
reverse_iterator& operator+=(difference_type n)
{
current_ -= n;
return *this;
}
reverse_iterator operator-(difference_type n) const
{
return reverse_iterator{current_ + n};
}
reverse_iterator& operator-=(difference_type n)
{
current_ += n;
return *this;
}
auto operator[](difference_type n) const
{
return current_[-n - 1];
}
protected:
Iterator current_;
};
template<class Iterator1, class Iterator2>
bool operator==(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() == rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator<(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() > rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator!=(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() != rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator>(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() < rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator>=(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() <= rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator<=(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
{
return lhs.base() >= rhs.base();
}
template<class Iterator1, class Iterator2>
auto operator-(const reverse_iterator<Iterator1>& lhs,
const reverse_iterator<Iterator2>& rhs)
-> decltype(rhs.base() - lhs.base())
{
return rhs.base() - lhs.base();
}
template<class Iterator>
reverse_iterator<Iterator> operator+(
typename reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& it
)
{
return reverse_iterator<Iterator>{it.base() - n};
}
template<class Iterator>
reverse_iterator<Iterator> make_reverse_iterator(Iterator it)
{
return reverse_iterator<Iterator>(it);
}
template<class Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
using container_type = Container;
explicit back_insert_iterator(Container& cont)
: container{std::addressof(cont)}
{ }
back_insert_iterator& operator=(const typename container_type::value_type& value)
{
container->push_back(value);
return *this;
}
back_insert_iterator& operator=(typename container_type::value_type&& value)
{
container->push_back(move(value));
return *this;
}
back_insert_iterator& operator*()
{
return *this;
}
back_insert_iterator& operator++()
{
return *this;
}
back_insert_iterator operator++(int)
{
return *this;
}
protected:
Container* container;
};
template<class Container>
back_insert_iterator<Container> back_inserter(Container& cont)
{
return back_insert_iterator<Container>(cont);
}
template<class Container>
class front_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
using container_type = Container;
explicit front_insert_iterator(Container& cont)
: container{std::addressof(cont)}
{ }
front_insert_iterator& operator=(const typename container_type::value_type& value)
{
container->push_front(value);
return *this;
}
front_insert_iterator& operator=(typename container_type::value_type&& value)
{
container->push_front(move(value));
return *this;
}
front_insert_iterator& operator*()
{
return *this;
}
front_insert_iterator& operator++()
{
return *this;
}
front_insert_iterator operator++(int)
{
return *this;
}
protected:
Container* container;
};
template<class Container>
front_insert_iterator<Container> front_inserter(Container& cont)
{
return front_insert_iterator<Container>(cont);
}
template<class Container>
class insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
using container_type = Container;
explicit insert_iterator(Container& cont, typename Container::iterator i)
: container{std::addressof(cont)}, iter{i}
{ }
insert_iterator& operator=(const typename container_type::value_type& value)
{
iter = container.insert(iter, value);
++iter;
return *this;
}
insert_iterator& operator=(typename container_type::value_type&& value)
{
iter = container.insert(iter, move(value));
++iter;
return *this;
}
insert_iterator& operator*()
{
return *this;
}
insert_iterator& operator++()
{
return *this;
}
insert_iterator operator++(int)
{
return *this;
}
protected:
Container* container;
typename Container::iterator iter;
};
template<class Container>
insert_iterator<Container> inserter(Container& cont, typename Container::iterator i)
{
return insert_iterator<Container>(cont, i);
}
namespace aux
{
template<class Iterator, class = void>
struct move_it_get_reference
{
using type = typename iterator_traits<Iterator>::reference;
};
template<class Iterator>
struct move_it_get_reference<
Iterator, enable_if_t<
is_reference<typename iterator_traits<Iterator>::reference>::value,
void
>
>
{
using type = remove_reference_t<typename iterator_traits<Iterator>::reference>&&;
};
}
template<class Iterator>
class move_iterator
{
public:
using iterator_type = Iterator;
using pointer = iterator_type;
using difference_type = typename iterator_traits<iterator_type>::difference_type;
using value_type = typename iterator_traits<iterator_type>::value_type;
using iterator_category = typename iterator_traits<iterator_type>::iterator_category;
using reference = typename aux::move_it_get_reference<iterator_type>::type;
move_iterator()
: current_{}
{ }
explicit move_iterator(iterator_type i)
: current_{i}
{ }
template<class U>
move_iterator(const move_iterator<U>& other)
: current_{other.current_}
{ }
template<class U>
move_iterator& operator=(const move_iterator<U>& other)
{
current_ = other.current_;
return *this;
}
iterator_type base() const
{
return current_;
}
reference operator*() const
{
return static_cast<reference>(*current_);
}
pointer operator->() const
{
return current_;
}
move_iterator& operator++()
{
++current_;
return *this;
}
move_iterator operator++(int)
{
auto tmp = *this;
++current_;
return tmp;
}
move_iterator& operator--()
{
--current_;
return *this;
}
move_iterator operator--(int)
{
auto tmp = *this;
--current_;
return tmp;
}
move_iterator operator+(difference_type n) const
{
return move_iterator(current_ + n);
}
move_iterator& operator+=(difference_type n)
{
current_ += n;
return *this;
}
move_iterator operator-(difference_type n) const
{
return move_iterator(current_ - n);
}
move_iterator& operator-=(difference_type n)
{
current_ -= n;
return *this;
}
auto operator[](difference_type idx) const
{
return move(current_[idx]);
}
private:
iterator_type current_;
};
template<class Iterator1, class Iterator2>
bool operator==(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return lhs.base() == rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator!=(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return lhs.base() != rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator<(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return lhs.base() < rhs.base();
}
template<class Iterator1, class Iterator2>
bool operator<=(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return !(rhs < lhs);
}
template<class Iterator1, class Iterator2>
bool operator>(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return rhs < lhs;
}
template<class Iterator1, class Iterator2>
bool operator>=(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
{
return !(lhs < rhs);
}
template<class Iterator1, class Iterator2>
auto operator-(const move_iterator<Iterator1>& lhs,
const move_iterator<Iterator2>& rhs)
-> decltype(rhs.base() - lhs.base())
{
return lhs.base() - rhs.base();
}
template<class Iterator>
move_iterator<Iterator> operator+(
typename move_iterator<Iterator>::difference_type n,
const move_iterator<Iterator>& it
)
{
return it + n;
}
template<class Iterator>
move_iterator<Iterator> make_move_iterator(Iterator it)
{
return move_iterator<Iterator>(it);
}
template<class T, class Char = char, class Traits = char_traits<Char>,
class Distance = ptrdiff_t>
class istream_iterator
: public iterator<input_iterator_tag, T, Distance, const T*, const T&>
{
public:
using char_type = Char;
using traits_type = Traits;
using istream_type = basic_istream<char_type, traits_type>;
istream_iterator()
: is_{nullptr}, value_{}
{ }
istream_iterator(istream_type& is)
: is_{&is}, value_{}
{ }
istream_iterator(const istream_iterator&) = default;
~istream_iterator() = default;
const T& operator*() const
{
return value_;
}
const T* operator->() const
{
return &(operator*());
}
istream_iterator& operator++()
{
if (is_)
(*is_) >> value_;
return *this;
}
istream_iterator operator++(int)
{
auto tmp{*this};
if (is_)
(*is_) >> value_;
return tmp;
}
private:
basic_istream<char_type, traits_type>* is_;
T value_;
friend bool operator==<>(const istream_iterator&,
const istream_iterator&);
friend bool operator!=<>(const istream_iterator&,
const istream_iterator&);
};
template<class T, class Char, class Traits, class Distance>
bool operator==(const istream_iterator<T, Char, Traits, Distance>& lhs,
const istream_iterator<T, Char, Traits, Distance>& rhs)
{
return lhs.is_ == rhs.is_;
}
template<class T, class Char, class Traits, class Distance>
bool operator!=(const istream_iterator<T, Char, Traits, Distance>& lhs,
const istream_iterator<T, Char, Traits, Distance>& rhs)
{
return !(lhs == rhs);
}
template<class T, class Char = char, class Traits = char_traits<Char>>
class ostream_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
using char_type = Char;
using traits_type = Traits;
using ostream_type = basic_ostream<char_type, traits_type>;
ostream_iterator(ostream_type& os)
: os_{&os}, delim_{nullptr}
{ }
ostream_iterator(ostream_type& os, const char_type* delim)
: os_{&os}, delim_{delim}
{ }
ostream_iterator(const ostream_iterator&) = default;
~ostream_iterator() = default;
ostream_iterator& operator=(const T& value)
{
os_ << value;
if (delim_)
os_ << delim_;
return *this;
}
ostream_iterator& operator*() const
{
return *this;
}
ostream_iterator& operator++()
{
return *this;
}
ostream_iterator& operator++(int)
{
return *this;
}
private:
basic_ostream<char_type, traits_type>* os_;
const char_type* delim_;
};
template<class Char, class Traits>
class istreambuf_iterator
: public iterator<input_iterator_tag, Char, typename Traits::off_type, Char*, Char>
{
public:
using char_type = Char;
using traits_type = Traits;
using int_type = typename traits_type::int_type;
using streambuf_type = basic_streambuf<char_type, traits_type>;
using istream_type = basic_istream<char_type, traits_type>;
class proxy_type
{
public:
proxy_type(int_type c, streambuf_type* sbuf)
: char_{c}, sbuf_{sbuf}
{ }
char_type operator*()
{
return traits_type::to_char_type(char_);
}
private:
int_type char_;
streambuf_type* sbuf_;
};
constexpr istreambuf_iterator() noexcept
: sbuf_{nullptr}
{ }
istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
~istreambuf_iterator() = default;
istreambuf_iterator(istream_type& is) noexcept
: sbuf_{is.rdbuf()}
{ }
istreambuf_iterator(streambuf_type* sbuf) noexcept
: sbuf_{sbuf}
{ }
istreambuf_iterator(const proxy_type& proxy) noexcept
: sbuf_{proxy.sbuf_}
{ }
char_type operator*()
{
if (sbuf_)
{
auto res = sbuf_->sgetc();
if (res == traits_type::eof())
sbuf_ = nullptr;
return res;
}
else
return traits_type::eof();
}
istreambuf_iterator& operator++()
{
if (sbuf_)
sbuf_->sbumpc();
return *this;
}
proxy_type operator++(int)
{
if (sbuf_)
return proxy_type{sbuf_->sbumpc(), sbuf_};
else
return proxy_type{traits_type::eof(), nullptr};
}
bool equal(const istreambuf_iterator& rhs) const
{
if ((sbuf_ == nullptr && rhs.sbuf_ == nullptr) ||
(sbuf_ != nullptr && rhs.sbuf_ != nullptr))
return true;
else
return false;
}
private:
streambuf_type* sbuf_;
};
template<class Char, class Traits>
bool operator==(const istreambuf_iterator<Char, Traits>& lhs,
const istreambuf_iterator<Char, Traits>& rhs)
{
return lhs.equal(rhs);
}
template<class Char, class Traits>
bool operator!=(const istreambuf_iterator<Char, Traits>& lhs,
const istreambuf_iterator<Char, Traits>& rhs)
{
return !lhs.equal(rhs);
}
template<class Char, class Traits>
class ostreambuf_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
using char_type = Char;
using traits_type = Traits;
using streambuf_type = basic_streambuf<char_type, traits_type>;
using ostream_type = basic_ostream<char_type, traits_type>;
ostreambuf_iterator(ostream_type& os) noexcept
: sbuf_{os.rdbuf()}
{ }
ostreambuf_iterator(streambuf_type* sbuf) noexcept
: sbuf_{sbuf}
{ }
ostreambuf_iterator& operator=(char_type c)
{
if (!failed() && sbuf_->sputc(c) == traits_type::eof())
failed_ = true;
return *this;
}
ostreambuf_iterator& operator*()
{
return *this;
}
ostreambuf_iterator& operator++()
{
return *this;
}
ostreambuf_iterator& operator++(int)
{
return *this;
}
bool failed() const noexcept
{
return failed_;
}
private:
streambuf_type* sbuf_;
bool failed_{false};
};
template<class Container>
auto begin(Container& c) -> decltype(c.begin())
{
return c.begin();
}
template<class Container>
auto begin(const Container& c) -> decltype(c.begin())
{
return c.begin();
}
template<class Container>
auto end(Container& c) -> decltype(c.end())
{
return c.end();
}
template<class Container>
auto end(const Container& c) -> decltype(c.end())
{
return c.end();
}
template<class T, size_t N>
constexpr T* begin(T (&array)[N]) noexcept
{
return array;
}
template<class T, size_t N>
constexpr T* end(T (&array)[N]) noexcept
{
return array + N;
}
template<class Container>
constexpr auto cbegin(const Container& c) noexcept(noexcept(std::begin(c)))
-> decltype(std::begin(c))
{
return std::begin(c);
}
template<class Container>
constexpr auto cend(const Container& c) noexcept(noexcept(std::end(c)))
-> decltype(std::end(c))
{
return std::end(c);
}
template<class Container>
auto rbegin(Container& c) -> decltype(c.rbegin())
{
return c.rbegin();
}
template<class Container>
auto rbegin(const Container& c) -> decltype(c.rbegin())
{
return c.rbegin();
}
template<class Container>
auto rend(Container& c) -> decltype(c.rend())
{
return c.rend();
}
template<class Container>
auto rend(const Container& c) -> decltype(c.rend())
{
return c.rend();
}
template<class T, size_t N>
reverse_iterator<T*> rbegin(T (&array)[N])
{
return reverse_iterator<T*>{array + N};
}
template<class T, size_t N>
reverse_iterator<T*> rend(T (&array)[N])
{
return reverse_iterator<T*>{array};
}
template<class T>
reverse_iterator<const T*> rbegin(initializer_list<T> init)
{
return reverse_iterator<const T*>{init.end()};
}
template<class T>
reverse_iterator<const T*> rend(initializer_list<T> init)
{
return reverse_iterator<const T*>{init.begin()};
}
template<class Container>
auto crbegin(const Container& c) -> decltype(std::rbegin(c))
{
return std::rbegin(c);
}
template<class Container>
auto crend(const Container& c) -> decltype(std::rend(c))
{
return std::rend(c);
}
template<class Container>
constexpr auto size(const Container& c) -> decltype(c.size())
{
return c.size();
}
template<class T, size_t N>
constexpr size_t size(T (&array)[N]) noexcept
{
return N;
}
template<class Container>
constexpr auto empty(const Container& c) -> decltype(c.empty())
{
return c.empty();
}
template<class T, size_t N>
constexpr bool empty(T (&array)[N]) noexcept
{
return false;
}
template<class T>
constexpr bool empty(initializer_list<T> init) noexcept
{
return init.size() == 0;
}
template<class Container>
constexpr auto data(Container& c) -> decltype(c.data())
{
return c.data();
}
template<class Container>
constexpr auto data(const Container& c) -> decltype(c.data())
{
return c.data();
}
template<class T, size_t N>
constexpr T* data(T (&array)[N]) noexcept
{
return array;
}
template<class T>
constexpr const T* data(initializer_list<T> init) noexcept
{
return init.begin();
}
}
#endif
HelenOS homepage, sources at GitHub