Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions asio/include/asio/ip/address_iterator_v6.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
//
// ip/address_iterator_v6.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASIO_IP_ADDRESS_ITERATOR_V6_HPP
#define ASIO_IP_ADDRESS_ITERATOR_V6_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/ip/address_v6.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {
namespace ip {

/// An input iterator that can be used for traversing IPv6 addresses.
/**
* In addition to satisfying the input iterator requirements, this iterator
* also supports decrement.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
class address_iterator_v6
{
public:
/// The type of the elements pointed to by the iterator.
typedef address_v6 value_type;

/// Distance between two iterators.
typedef std::ptrdiff_t difference_type;

/// The type of a pointer to an element pointed to by the iterator.
typedef const address_v6* pointer;

/// The type of a reference to an element pointed to by the iterator.
typedef const address_v6& reference;

/// Denotes that the iterator satisfies the input iterator requirements.
typedef std::input_iterator_tag iterator_category;

/// Construct an iterator that points to the specified address.
address_iterator_v6(const address_v6& addr) ASIO_NOEXCEPT
: address_(addr)
{
}

/// Copy constructor.
address_iterator_v6(const address_iterator_v6& other) ASIO_NOEXCEPT
: address_(other.address_)
{
}

#if defined(ASIO_HAS_MOVE)
/// Move constructor.
address_iterator_v6(address_iterator_v6&& other) ASIO_NOEXCEPT
: address_(ASIO_MOVE_CAST(address_v6)(other.address_))
{
}
#endif // defined(ASIO_HAS_MOVE)

/// Assignment operator.
address_iterator_v6& operator=(
const address_iterator_v6& other) ASIO_NOEXCEPT
{
address_ = other.address_;
return *this;
}

#if defined(ASIO_HAS_MOVE)
/// Move assignment operator.
address_iterator_v6& operator=(
address_iterator_v6&& other) ASIO_NOEXCEPT
{
address_ = ASIO_MOVE_CAST(address_v6)(other.address_);
return *this;
}
#endif // defined(ASIO_HAS_MOVE)

/// Dereference the iterator.
const address_v6& operator*() const ASIO_NOEXCEPT
{
return address_;
}

/// Dereference the iterator.
const address_v6* operator->() const ASIO_NOEXCEPT
{
return &address_;
}

/// Pre-increment operator.
address_iterator_v6& operator++() ASIO_NOEXCEPT
{
address_ = address_.successor_();
return *this;
}

/// Post-increment operator.
address_iterator_v6 operator++(int) ASIO_NOEXCEPT
{
address_iterator_v6 tmp(*this);
++*this;
return tmp;
}

/// Pre-decrement operator.
address_iterator_v6& operator--() ASIO_NOEXCEPT
{
address_ = address_.predeccessor_();
return *this;
}

/// Post-decrement operator.
address_iterator_v6 operator--(int)
{
address_iterator_v6 tmp(*this);
--*this;
return tmp;
}

/// Compare two addresses for equality.
friend bool operator==(const address_iterator_v6& a,
const address_iterator_v6& b)
{
return a.address_ == b.address_;
}

/// Compare two addresses for inequality.
friend bool operator!=(const address_iterator_v6& a,
const address_iterator_v6& b)
{
return a.address_ != b.address_;
}

private:
address_v6 address_;
};

} // namespace ip
} // namespace asio

#include "asio/detail/pop_options.hpp"

#endif // ASIO_IP_ADDRESS_ITERATOR_V6_HPP
128 changes: 128 additions & 0 deletions asio/include/asio/ip/address_range_v6.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//
// ip/address_range_v6.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASIO_IP_ADDRESS_RANGE_v6_HPP
#define ASIO_IP_ADDRESS_RANGE_v6_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/ip/address_iterator_v6.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {
namespace ip {

/// Represents a range of IPv6 addresses.
/**
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
class address_range_v6
{
public:
/// The type of an iterator that points into the range.
typedef address_iterator_v6 iterator;

/// Construct an empty range.
address_range_v6() ASIO_NOEXCEPT;

/// Construct an range that represents the given range of addresses.
explicit address_range_v6(const address_iterator_v6& first,
const address_iterator_v6& last) ASIO_NOEXCEPT
: begin_(first),
end_(last)
{
}

/// Copy constructor.
address_range_v6(const address_range_v6& other) ASIO_NOEXCEPT
: begin_(other.begin_),
end_(other.end_)
{
}

#if defined(ASIO_HAS_MOVE)
/// Move constructor.
address_range_v6(address_range_v6&& other) ASIO_NOEXCEPT
: begin_(ASIO_MOVE_CAST(address_iterator_v6)(other.begin_)),
end_(ASIO_MOVE_CAST(address_iterator_v6)(other.end_))
{
}
#endif // defined(ASIO_HAS_MOVE)

/// Assignment operator.
address_range_v6& operator=(
const address_range_v6& other) ASIO_NOEXCEPT
{
begin_ = other.begin_;
end_ = other.end_;
return *this;
}

#if defined(ASIO_HAS_MOVE)
/// Move assignment operator.
address_range_v6& operator=(
address_range_v6&& other) ASIO_NOEXCEPT
{
begin_ = ASIO_MOVE_CAST(address_iterator_v6)(other.begin_);
end_ = ASIO_MOVE_CAST(address_iterator_v6)(other.end_);
return *this;
}
#endif // defined(ASIO_HAS_MOVE)

/// Obtain an iterator that points to the start of the range.
iterator begin() const ASIO_NOEXCEPT
{
return begin_;
}

/// Obtain an iterator that points to the end of the range.
iterator end() const ASIO_NOEXCEPT
{
return end_;
}

/// Determine whether the range is empty.
bool empty() const ASIO_NOEXCEPT
{
return size() == 0;
}

// FIXME: range of 128bit IPv6-addresses doesn't fit into std::size_t
/// Return the size of the range.
std::size_t size() const ASIO_NOEXCEPT
{
// return end_->to_ulong() - begin_->to_ulong();
return 0;
}

/// Find an address in the range.
iterator find(const address_v6& addr) const ASIO_NOEXCEPT
{
return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_;
}

private:
address_iterator_v6 begin_;
address_iterator_v6 end_;
};

} // namespace ip
} // namespace asio

#include "asio/detail/pop_options.hpp"

#endif // ASIO_IP_ADDRESS_RANGE_V6_HPP
9 changes: 9 additions & 0 deletions asio/include/asio/ip/address_v6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
namespace asio {
namespace ip {

class network_v6;
class address_iterator_v6;

/// Implements IP version 6 style addresses.
/**
* The asio::ip::address_v6 class provides the ability to use and
Expand All @@ -44,6 +47,9 @@ namespace ip {
class address_v6
{
public:
friend class network_v6;
friend class address_iterator_v6;

/// The type used to represent an address as an array of bytes.
/**
* @note This type is defined in terms of the C++0x template @c std::array
Expand Down Expand Up @@ -223,6 +229,9 @@ class address_v6

// The scope ID associated with the address.
unsigned long scope_id_;

ASIO_DECL address_v6 successor_() const;
ASIO_DECL address_v6 predeccessor_() const;
};

/// Create an IPv6 address from raw bytes and scope ID.
Expand Down
56 changes: 56 additions & 0 deletions asio/include/asio/ip/impl/address_v6.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,62 @@ address_v6 make_address_v6(
return address_v6(v6_bytes);
}

address_v6 address_v6::successor_() const
{
using namespace std; // For memcpy.
detail::in6_addr_type addr;
memcpy(&addr, &addr_, sizeof( addr_));
bool valid = false;
for ( int i = 15; 0 <= i; --i)
{
if ( 0xff == addr.s6_addr[i])
addr.s6_addr[i] = 0;
else
{
++addr.s6_addr[i];
valid = true;
break;
}
}
if ( valid)
{
bytes_type bytes;
memcpy(bytes.data(), addr.s6_addr, 16);
// FIXME: take care about the scope
return address_v6( bytes, scope_id_);
}
else
return address_v6();
}

address_v6 address_v6::predeccessor_() const
{
using namespace std; // For memcpy.
detail::in6_addr_type addr;
memcpy(&addr, &addr_, sizeof( addr_));
bool valid = false;
for ( int i = 15; 0 <= i; --i)
{
if ( 0 == addr.s6_addr[i])
addr.s6_addr[i] = 0xff;
else
{
--addr.s6_addr[i];
valid = true;
break;
}
}
if ( valid)
{
bytes_type bytes;
memcpy(bytes.data(), addr.s6_addr, 16);
// FIXME: take care about the scope
return address_v6( bytes, scope_id_);
}
else
return address_v6();
}

} // namespace ip
} // namespace asio

Expand Down
Loading