sprout/checksum/sha1.hpp 追加

sprout/null_array.hpp -> sprout/pit.hpp リネーム
sprout/uuid.hpp 追加
This commit is contained in:
bolero-MURAKAMI 2011-10-25 18:16:27 +09:00
parent 9074c9a1cf
commit 0f8db75fca
22 changed files with 2126 additions and 86 deletions

View file

@ -6,7 +6,7 @@
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/array.hpp>
#include <sprout/null_array.hpp>
#include <sprout/pit.hpp>
#include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/iterator/operation.hpp>
@ -48,7 +48,7 @@ namespace sprout {
? sprout::fixed::detail::make_shuffle_indexes_1(
n,
sprout::random::uniform_int_distribution<std::ptrdiff_t>(0, n - 1)(sprout::forward<UniformRandomNumberGenerator>(g)),
sprout::fixed::iota(sprout::null_array<sprout::array<std::ptrdiff_t, N> >(), 0),
sprout::fixed::iota(sprout::pit<sprout::array<std::ptrdiff_t, N> >(), 0),
0
)
: sprout::array<std::ptrdiff_t, N>{{}}

View file

@ -43,7 +43,7 @@ namespace sprout {
SPROUT_STATIC_CONSTEXPR size_type static_size = N;
SPROUT_STATIC_CONSTEXPR size_type fixed_size = static_size;
public:
T elems[N ? N : 1];
value_type elems[static_size ? static_size : 1];
public:
void fill(const_reference value) {
std::fill_n(begin(), size(), value);
@ -114,13 +114,13 @@ namespace sprout {
}
// capacity:
SPROUT_CONSTEXPR size_type size() const SPROUT_NOEXCEPT {
return N;
return static_size;
}
SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT {
return size();
}
SPROUT_CONSTEXPR bool empty() const SPROUT_NOEXCEPT {
return N == 0;
return size() == 0;
}
// element access:
reference operator[](size_type i) {
@ -320,18 +320,18 @@ namespace std {
// get
//
template<std::size_t I, typename T, std::size_t N>
T& get(sprout::array<T, N>& arr) SPROUT_NOEXCEPT {
T& get(sprout::array<T, N>& t) SPROUT_NOEXCEPT {
static_assert(I < N, "get: index out of range");
return arr[I];
return t[I];
}
template<std::size_t I, typename T, std::size_t N>
SPROUT_CONSTEXPR T const& get(sprout::array<T, N> const& arr) SPROUT_NOEXCEPT {
SPROUT_CONSTEXPR T const& get(sprout::array<T, N> const& t) SPROUT_NOEXCEPT {
static_assert(I < N, "get: index out of range");
return arr[I];
return t[I];
}
template<std::size_t I, typename T, std::size_t N>
T&& get(sprout::array<T, N>&& arr) SPROUT_NOEXCEPT {
return std::move(std::get<I>(arr));
T&& get(sprout::array<T, N>&& t) SPROUT_NOEXCEPT {
return std::move(std::get<I>(t));
}
} // namespace std

313
sprout/checksum/sha1.hpp Normal file
View file

@ -0,0 +1,313 @@
#ifndef SPROUT_CHECKSUM_SHA1_HPP
#define SPROUT_CHECKSUM_SHA1_HPP
#include <cstddef>
#include <cstdint>
#include <climits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/array.hpp>
#include <sprout/sub_array.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/bytes_iterator.hpp>
#include <sprout/range/algorithm/fixed/copy.hpp>
#include <sprout/operation/fixed/set.hpp>
namespace sprout {
static_assert(CHAR_BIT == 8, "CHAR_BIT == 8");
namespace detail {
SPROUT_CONSTEXPR inline std::uint32_t sha1_left_rotate(std::uint32_t x, std::size_t n) {
return (x << n) ^ (x >> (32 - n));
}
} // namespace detail
//
// sha1
//
class sha1 {
public:
typedef sprout::array<std::uint8_t, 20> value_type;
private:
sprout::array<std::uint32_t, 5> h_;
sprout::array<std::uint8_t, 64> block_;
std::size_t block_byte_index_;
std::size_t byte_count_;
private:
SPROUT_CONSTEXPR sha1(
sprout::array<std::uint32_t, 5> const& h,
sprout::array<std::uint8_t, 64> const& block,
std::size_t block_byte_index,
std::size_t byte_count
)
: h_(h)
, block_(block)
, block_byte_index_(block_byte_index)
, byte_count_(byte_count)
{}
SPROUT_CONSTEXPR std::uint32_t calc_w(std::size_t i) const {
return i < 16
? (block_[i * 4] << 24)
| (block_[i * 4 + 1] << 16)
| (block_[i * 4 + 2] << 8)
| (block_[i * 4 + 3])
: sprout::detail::sha1_left_rotate(
calc_w(i - 3) ^ calc_w(i - 8) ^ calc_w(i - 14) ^ calc_w(i - 16),
1
)
;
}
SPROUT_CONSTEXPR sha1 process(
sprout::array<std::uint32_t, 5> const& h,
sprout::array<std::uint8_t, 64> const& block,
std::size_t block_byte_index,
std::size_t byte_count
) const
{
return block_byte_index != 64
? sha1(
h,
block,
block_byte_index,
byte_count
)
: sha1(
h,
block,
0,
byte_count
).process_block()
;
}
SPROUT_CONSTEXPR sha1 process_block_2(
std::uint32_t a,
std::uint32_t b,
std::uint32_t c,
std::uint32_t d,
std::uint32_t e,
std::size_t i,
std::uint32_t f,
std::uint32_t k
) const
{
return process_block_1(
sprout::detail::sha1_left_rotate(a, 5) + f + e + k + calc_w(i),
a,
sprout::detail::sha1_left_rotate(b, 30),
c,
d,
i + 1
);
}
SPROUT_CONSTEXPR sha1 process_block_1(
std::uint32_t a,
std::uint32_t b,
std::uint32_t c,
std::uint32_t d,
std::uint32_t e,
std::size_t i = 0
) const
{
return i < 80
? process_block_2(
a,
b,
c,
d,
e,
i,
i < 20 ? (b & c) | (~b & d)
: i < 40 ? b ^ c ^ d
: i < 60 ? (b & c) | (b & d) | (c & d)
: b ^ c ^ d
,
i < 20 ? 0x5A827999
: i < 40 ? 0x6ED9EBA1
: i < 60 ? 0x8F1BBCDC
: 0xCA62C1D6
)
: sha1(
sprout::array<std::uint32_t, 5>{{h_[0] + a, h_[1] + b, h_[2] + c, h_[3] + d, h_[4] + e}},
block_,
block_byte_index_,
byte_count_
)
;
}
SPROUT_CONSTEXPR sha1 process_block() const {
return process_block_1(h_[0], h_[1], h_[2], h_[3], h_[4]);
}
template<typename Iterator, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 64,
sha1
>::type process_block_impl(
Iterator first,
Iterator last,
Args... args
) const
{
return first == last ? process(
h_,
sprout::make_array<std::uint8_t>(args...),
64,
byte_count_ + 64
)
: process(
h_,
sprout::make_array<std::uint8_t>(args...),
64,
byte_count_ + 64
).process_block_impl(first, last)
;
}
template<typename Iterator, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) != 64,
sha1
>::type process_block_impl(
Iterator first,
Iterator last,
Args... args
) const
{
return first == last ? process(
h_,
sprout::get_fixed(sprout::range::fixed::copy(sprout::make_array<std::uint8_t>(args...), sprout::sub(block_, block_byte_index_))),
block_byte_index_ + sizeof...(Args),
byte_count_ + sizeof...(Args)
)
: block_byte_index_ + sizeof...(Args) == 64 ? process(
h_,
sprout::get_fixed(sprout::range::fixed::copy(sprout::make_array<std::uint8_t>(args...), sprout::sub(block_, block_byte_index_))),
block_byte_index_ + sizeof...(Args),
byte_count_ + sizeof...(Args)
).process_block_impl(first, last)
: process_block_impl(sprout::next(first), last, args..., *first)
;
}
template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 64,
sha1
>::type process_padding(
Args... args
) const
{
return process(
h_,
sprout::make_array<std::uint8_t>(args...),
64,
byte_count_ + 64
).process_padding()
;
}
template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) != 64,
sha1
>::type process_padding(
Args... args
) const
{
return block_byte_index_ + sizeof...(Args) == 56 ? process(
h_,
sprout::get_fixed(sprout::range::fixed::copy(sprout::make_array<std::uint8_t>(args...), sprout::sub(block_, block_byte_index_))),
block_byte_index_ + sizeof...(Args),
byte_count_ + sizeof...(Args)
)
: block_byte_index_ + sizeof...(Args) == 64 ? process(
h_,
sprout::get_fixed(sprout::range::fixed::copy(sprout::make_array<std::uint8_t>(args...), sprout::sub(block_, block_byte_index_))),
block_byte_index_ + sizeof...(Args),
byte_count_ + sizeof...(Args)
).process_padding()
: process_padding(args..., static_cast<std::uint8_t>(0))
;
}
SPROUT_CONSTEXPR sha1 process_append() const {
return process(
h_,
sprout::get_fixed(sprout::range::fixed::copy(
sprout::array<std::uint8_t, 8>{{
static_cast<std::uint8_t>(0),
static_cast<std::uint8_t>(0),
static_cast<std::uint8_t>(0),
static_cast<std::uint8_t>(0),
static_cast<std::uint8_t>((byte_count_ * 8 >> 24) & 0xFF),
static_cast<std::uint8_t>((byte_count_ * 8 >> 16) & 0xFF),
static_cast<std::uint8_t>((byte_count_ * 8 >> 8) & 0xFF),
static_cast<std::uint8_t>((byte_count_ * 8) & 0xFF)
}},
sprout::sub(block_, block_byte_index_)
)),
block_byte_index_ + 8,
byte_count_ + 8
);
}
SPROUT_CONSTEXPR value_type make_value() const {
return value_type{{
static_cast<std::uint8_t>((h_[0] >> 24) & 0xFF),
static_cast<std::uint8_t>((h_[0] >> 16) & 0xFF),
static_cast<std::uint8_t>((h_[0] >> 8) & 0xFF),
static_cast<std::uint8_t>((h_[0]) & 0xFF),
static_cast<std::uint8_t>((h_[1] >> 24) & 0xFF),
static_cast<std::uint8_t>((h_[1] >> 16) & 0xFF),
static_cast<std::uint8_t>((h_[1] >> 8) & 0xFF),
static_cast<std::uint8_t>((h_[1]) & 0xFF),
static_cast<std::uint8_t>((h_[2] >> 24) & 0xFF),
static_cast<std::uint8_t>((h_[2] >> 16) & 0xFF),
static_cast<std::uint8_t>((h_[2] >> 8) & 0xFF),
static_cast<std::uint8_t>((h_[2]) & 0xFF),
static_cast<std::uint8_t>((h_[3] >> 24) & 0xFF),
static_cast<std::uint8_t>((h_[3] >> 16) & 0xFF),
static_cast<std::uint8_t>((h_[3] >> 8) & 0xFF),
static_cast<std::uint8_t>((h_[3]) & 0xFF),
static_cast<std::uint8_t>((h_[4] >> 24) & 0xFF),
static_cast<std::uint8_t>((h_[4] >> 16) & 0xFF),
static_cast<std::uint8_t>((h_[4] >> 8) & 0xFF),
static_cast<std::uint8_t>((h_[4]) & 0xFF)
}};
}
public:
SPROUT_CONSTEXPR sha1()
: h_{{0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}}
, block_{{}}
, block_byte_index_()
, byte_count_()
{}
SPROUT_CONSTEXPR sha1 process_byte(std::uint8_t byte) const {
return process(
h_,
sprout::fixed::set(block_, block_.begin() + block_byte_index_, byte),
block_byte_index_ + 1,
byte_count_ + 1
);
}
template<typename Iterator>
SPROUT_CONSTEXPR sha1 process_block(Iterator bytes_begin, Iterator bytes_end) const {
return process_block_impl(
sprout::make_bytes_iterator(bytes_begin),
sprout::make_bytes_iterator(bytes_end)
);
}
template<typename Iterator>
SPROUT_CONSTEXPR sha1 process_bytes(Iterator buffer, std::size_t byte_count) const {
return process_block(buffer, sprout::next(buffer, byte_count));
}
template<typename Range>
SPROUT_CONSTEXPR sha1 process_range(Range const& bytes_range) const {
return process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
}
SPROUT_CONSTEXPR value_type checksum() const {
return process_byte(0x80).process_padding().process_append().make_value();
}
SPROUT_CONSTEXPR value_type operator()() const {
return checksum();
}
};
} // namespace sprout
#endif // #ifndef SPROUT_CHECKSUM_SHA1_HPP

View file

@ -126,6 +126,17 @@ namespace sprout {
? false
: sprout::detail::lexicographical_compare(sprout::next(first1), last1, sprout::next(first2), last2, comp);
}
//
// find
//
template<typename Iterator, typename T>
SPROUT_CONSTEXPR Iterator find(Iterator first, Iterator last, T const& value) {
return first == last || *first == value
? first
: sprout::detail::find(sprout::next(first), last, value)
;
}
} // namespace detail
} // namespace sprout

View file

@ -0,0 +1,412 @@
#ifndef SPROUT_DETAIL_IO_IOS_STATE_HPP
#define SPROUT_DETAIL_IO_IOS_STATE_HPP
#include <string>
#include <ios>
#include <ostream>
#include <streambuf>
#include <locale>
#include <sprout/config.hpp>
#include <sprout/detail/io_fwd.hpp>
namespace sprout {
namespace detail {
namespace io {
class ios_flags_saver {
public:
typedef std::ios_base state_type;
typedef std::ios_base::fmtflags aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit ios_flags_saver(state_type& s)
: s_save_(s)
, a_save_(s.flags())
{}
ios_flags_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.flags(a))
{}
ios_flags_saver& operator=(ios_flags_saver const&) = delete;
~ios_flags_saver() {
this->restore();
}
void restore() {
s_save_.flags(a_save_);
}
};
class ios_precision_saver {
public:
typedef std::ios_base state_type;
typedef std::streamsize aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit ios_precision_saver(state_type& s)
: s_save_(s)
, a_save_(s.precision())
{}
ios_precision_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.precision(a))
{}
ios_precision_saver& operator=(ios_precision_saver const&) = delete;
~ios_precision_saver() {
this->restore();
}
void restore() {
s_save_.precision(a_save_);
}
};
class ios_width_saver {
public:
typedef std::ios_base state_type;
typedef std::streamsize aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit ios_width_saver(state_type& s)
: s_save_(s)
, a_save_(s.width())
{}
ios_width_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.width(a))
{}
ios_width_saver& operator=(ios_width_saver const&) = delete;
~ios_width_saver() {
this->restore();
}
void restore() {
s_save_.width(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_iostate_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef std::ios_base::iostate aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_iostate_saver(state_type& s)
: s_save_(s)
, a_save_(s.rdstate())
{}
basic_ios_iostate_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.rdstate())
{
s.clear(a);
}
basic_ios_iostate_saver& operator=(basic_ios_iostate_saver const&) = delete;
~basic_ios_iostate_saver() {
this->restore();
}
void restore() {
s_save_.clear(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_exception_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef std::ios_base::iostate aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_exception_saver(state_type& s)
: s_save_(s)
, a_save_(s.exceptions())
{}
basic_ios_exception_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.exceptions())
{
s.exceptions(a);
}
basic_ios_exception_saver& operator=(basic_ios_exception_saver const&) = delete;
~basic_ios_exception_saver() {
this->restore();
}
void restore() {
s_save_.exceptions(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_tie_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef std::basic_ostream<Elem, Traits>* aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_tie_saver(state_type& s)
: s_save_(s)
, a_save_(s.tie())
{}
basic_ios_tie_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.tie(a))
{}
basic_ios_tie_saver& operator=(basic_ios_tie_saver const&) = delete;
~basic_ios_tie_saver() {
this->restore();
}
void restore() {
s_save_.tie(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_rdbuf_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef std::basic_streambuf<Elem, Traits>* aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_rdbuf_saver(state_type& s)
: s_save_(s)
, a_save_(s.rdbuf())
{}
basic_ios_rdbuf_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.rdbuf(a))
{}
basic_ios_rdbuf_saver& operator=(basic_ios_rdbuf_saver const&) = delete;
~basic_ios_rdbuf_saver() {
this->restore();
}
void restore() {
s_save_.rdbuf(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_fill_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef typename state_type::char_type aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_fill_saver(state_type& s)
: s_save_(s)
, a_save_(s.fill())
{}
basic_ios_fill_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.fill(a))
{}
basic_ios_fill_saver& operator=(basic_ios_fill_saver const&) = delete;
~basic_ios_fill_saver() {
this->restore();
}
void restore() {
s_save_.fill(a_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_locale_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
typedef std::locale aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
public:
explicit basic_ios_locale_saver(state_type& s)
: s_save_(s)
, a_save_(s.getloc())
{}
basic_ios_locale_saver(state_type& s, aspect_type const& a)
: s_save_(s)
, a_save_(s.imbue(a))
{}
basic_ios_locale_saver& operator=(basic_ios_locale_saver const&) = delete;
~basic_ios_locale_saver() {
this->restore();
}
void restore() {
s_save_.imbue(a_save_);
}
};
class ios_iword_saver {
public:
typedef std::ios_base state_type;
typedef int index_type;
typedef long aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
index_type const i_save_;
public:
explicit ios_iword_saver(state_type& s, index_type i)
: s_save_(s)
, a_save_(s.iword(i))
, i_save_(i)
{}
ios_iword_saver(state_type& s, index_type i, aspect_type const& a)
: s_save_(s)
, a_save_(s.iword(i))
, i_save_(i)
{
s.iword(i) = a;
}
ios_iword_saver& operator=(ios_iword_saver const&) = delete;
~ios_iword_saver() {
this->restore();
}
void restore() {
s_save_.iword(i_save_) = a_save_;
}
};
class ios_pword_saver {
public:
typedef std::ios_base state_type;
typedef int index_type;
typedef void* aspect_type;
private:
state_type& s_save_;
aspect_type const a_save_;
index_type const i_save_;
public:
explicit ios_pword_saver(state_type& s, index_type i)
: s_save_(s)
, a_save_(s.pword(i))
, i_save_(i)
{}
ios_pword_saver(state_type& s, index_type i, aspect_type const& a)
: s_save_(s)
, a_save_(s.pword(i))
, i_save_(i)
{
s.pword(i) = a;
}
ios_pword_saver& operator=(ios_pword_saver const&) = delete;
~ios_pword_saver() {
this->restore();
}
void restore() {
s_save_.pword(i_save_) = a_save_;
}
};
class ios_base_all_saver {
public:
typedef std::ios_base state_type;
private:
state_type& s_save_;
state_type::fmtflags const a1_save_;
std::streamsize const a2_save_;
std::streamsize const a3_save_;
public:
explicit ios_base_all_saver(state_type& s)
: s_save_(s)
, a1_save_(s.flags())
, a2_save_(s.precision())
, a3_save_(s.width())
{}
ios_base_all_saver& operator=(ios_base_all_saver const&) = delete;
~ios_base_all_saver() {
this->restore();
}
void restore() {
s_save_.width(a3_save_);
s_save_.precision(a2_save_);
s_save_.flags(a1_save_);
}
};
template<typename Elem, typename Traits>
class basic_ios_all_saver {
public:
typedef std::basic_ios<Elem, Traits> state_type;
private:
state_type& s_save_;
typename state_type::fmtflags const a1_save_;
std::streamsize const a2_save_;
std::streamsize const a3_save_;
typename state_type::iostate const a4_save_;
typename state_type::iostate const a5_save_;
std::basic_ostream<Elem, Traits>* const a6_save_;
std::basic_streambuf<Elem, Traits>* const a7_save_;
typename state_type::char_type const a8_save_;
std::locale const a9_save_;
public:
explicit basic_ios_all_saver(state_type& s)
: s_save_(s)
, a1_save_(s.flags())
, a2_save_(s.precision())
, a3_save_(s.width())
, a4_save_(s.rdstate())
, a5_save_(s.exceptions())
, a6_save_(s.tie())
, a7_save_(s.rdbuf())
, a8_save_(s.fill())
, a9_save_(s.getloc())
{}
basic_ios_all_saver& operator=(basic_ios_all_saver const&) = delete;
~basic_ios_all_saver() {
this->restore();
}
void restore() {
s_save_.imbue(a9_save_);
s_save_.fill(a8_save_);
s_save_.rdbuf(a7_save_);
s_save_.tie(a6_save_);
s_save_.exceptions(a5_save_);
s_save_.clear(a4_save_);
s_save_.width(a3_save_);
s_save_.precision(a2_save_);
s_save_.flags(a1_save_);
}
};
class ios_all_word_saver {
public:
typedef std::ios_base state_type;
typedef int index_type;
private:
state_type& s_save_;
index_type const i_save_;
long const a1_save_;
void* const a2_save_;
public:
ios_all_word_saver(state_type& s, index_type i)
: s_save_(s)
, i_save_(i)
, a1_save_(s.iword(i))
, a2_save_(s.pword(i))
{}
ios_all_word_saver& operator=(ios_all_word_saver const&) = delete;
~ios_all_word_saver() {
this->restore();
}
void restore() {
s_save_.pword(i_save_) = a2_save_;
s_save_.iword(i_save_) = a1_save_;
}
};
} // namespace io
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_IO_IOS_STATE_HPP

71
sprout/detail/io_fwd.hpp Normal file
View file

@ -0,0 +1,71 @@
#ifndef SPROUT_DETAIL_IO_FWD_HPP
#define SPROUT_DETAIL_IO_FWD_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace detail {
namespace io {
class ios_flags_saver;
class ios_precision_saver;
class ios_width_saver;
class ios_base_all_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_iostate_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_exception_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_tie_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_rdbuf_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_fill_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_locale_saver;
template<typename Elem, typename Traits = std::char_traits<Elem> >
class basic_ios_all_saver;
typedef sprout::detail::io::basic_ios_iostate_saver<char> ios_iostate_saver;
typedef sprout::detail::io::basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
typedef sprout::detail::io::basic_ios_iostate_saver<char16_t> u16ios_iostate_saver;
typedef sprout::detail::io::basic_ios_iostate_saver<char32_t> u32ios_iostate_saver;
typedef sprout::detail::io::basic_ios_exception_saver<char> ios_exception_saver;
typedef sprout::detail::io::basic_ios_exception_saver<wchar_t> wios_exception_saver;
typedef sprout::detail::io::basic_ios_exception_saver<char16_t> u16ios_exception_saver;
typedef sprout::detail::io::basic_ios_exception_saver<char32_t> u32ios_exception_saver;
typedef sprout::detail::io::basic_ios_tie_saver<char> ios_tie_saver;
typedef sprout::detail::io::basic_ios_tie_saver<wchar_t> wios_tie_saver;
typedef sprout::detail::io::basic_ios_tie_saver<char16_t> u16ios_tie_saver;
typedef sprout::detail::io::basic_ios_tie_saver<char32_t> u32ios_tie_saver;
typedef sprout::detail::io::basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
typedef sprout::detail::io::basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
typedef sprout::detail::io::basic_ios_rdbuf_saver<char16_t> u16ios_rdbuf_saver;
typedef sprout::detail::io::basic_ios_rdbuf_saver<char32_t> u32ios_rdbuf_saver;
typedef sprout::detail::io::basic_ios_fill_saver<char> ios_fill_saver;
typedef sprout::detail::io::basic_ios_fill_saver<wchar_t> wios_fill_saver;
typedef sprout::detail::io::basic_ios_fill_saver<char16_t> u16ios_fill_saver;
typedef sprout::detail::io::basic_ios_fill_saver<char32_t> u32ios_fill_saver;
typedef sprout::detail::io::basic_ios_locale_saver<char> ios_locale_saver;
typedef sprout::detail::io::basic_ios_locale_saver<wchar_t> wios_locale_saver;
typedef sprout::detail::io::basic_ios_locale_saver<char16_t> u16ios_locale_saver;
typedef sprout::detail::io::basic_ios_locale_saver<char32_t> u32ios_locale_saver;
typedef sprout::detail::io::basic_ios_all_saver<char> ios_all_saver;
typedef sprout::detail::io::basic_ios_all_saver<wchar_t> wios_all_saver;
typedef sprout::detail::io::basic_ios_all_saver<char16_t> u16ios_all_saver;
typedef sprout::detail::io::basic_ios_all_saver<char32_t> u32ios_all_saver;
class ios_iword_saver;
class ios_pword_saver;
class ios_all_word_saver;
} // namespace io
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_IO_FWD_HPP

47
sprout/endian_traits.hpp Normal file
View file

@ -0,0 +1,47 @@
#ifndef SPROUT_ENDIAN_TRAITS_HPP
#define SPROUT_ENDIAN_TRAITS_HPP
#include <cstddef>
#include <climits>
#include <sprout/config.hpp>
namespace sprout {
//
// big_endian_traits
//
template<typename T>
class big_endian_traits {
public:
typedef T type;
public:
static SPROUT_CONSTEXPR std::size_t size() {
return sizeof(type);
}
static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t i) {
return static_cast<unsigned char>(
(t & (UCHAR_MAX << CHAR_BIT * ((size() - 1) - i)))
>> CHAR_BIT * ((size() - 1) - i)
);
}
};
//
// little_endian_traits
//
template<typename T>
class little_endian_traits {
public:
typedef T type;
public:
static SPROUT_CONSTEXPR std::size_t size() {
return sizeof(type);
}
static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t i) {
return static_cast<unsigned char>(
(t & (UCHAR_MAX << CHAR_BIT * i))
>> CHAR_BIT * i
);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_ENDIAN_TRAITS_HPP

View file

@ -216,7 +216,7 @@ namespace sprout {
public:
typedef T* argument_type;
typedef std::size_t result_type;
public: \
public:
SPROUT_CONSTEXPR std::size_t operator()(T* v) const {
return sprout::hash_value(v);
}

View file

@ -0,0 +1,223 @@
#ifndef SPROUT_ITERATOR_BYTES_ITERATOR_HPP
#define SPROUT_ITERATOR_BYTES_ITERATOR_HPP
#include <cstddef>
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp>
#include <sprout/endian_traits.hpp>
namespace sprout {
//
// bytes_iterator
//
template<
typename Iterator,
typename Traits = sprout::big_endian_traits<typename std::iterator_traits<Iterator>::value_type>
>
class bytes_iterator
: public std::iterator<
typename std::iterator_traits<Iterator>::iterator_category,
unsigned char,
std::ptrdiff_t,
void,
unsigned char
>
{
public:
typedef Iterator base_type;
typedef Traits traits_type;
private:
typedef std::iterator<
typename std::iterator_traits<Iterator>::iterator_category,
unsigned char,
std::ptrdiff_t,
void,
unsigned char
> iterator_type;
public:
typedef typename iterator_type::iterator_category iterator_category;
typedef typename iterator_type::value_type value_type;
typedef typename iterator_type::difference_type difference_type;
typedef typename iterator_type::pointer pointer;
typedef typename iterator_type::reference reference;
private:
struct next_tag {};
struct prev_tag {};
struct ra_tag {};
private:
base_type it_;
difference_type i_;
private:
SPROUT_CONSTEXPR bytes_iterator(base_type it, difference_type i)
: it_(it)
, i_(i)
{}
SPROUT_CONSTEXPR bytes_iterator(base_type it, difference_type i, next_tag)
: it_(i / traits_type::size() == 0 ? it : sprout::next(it))
, i_(i % traits_type::size())
{}
SPROUT_CONSTEXPR bytes_iterator(base_type it, difference_type i, prev_tag)
: it_((i + 1 - traits_type::size()) / traits_type::size() == 0 ? it : sprout::prev(it))
, i_(i % traits_type::size() + traits_type::size())
{}
SPROUT_CONSTEXPR bytes_iterator(base_type it, difference_type i, ra_tag)
: it_(i >= 0
? sprout::next(it, i / traits_type::size())
: sprout::next(it, (i + 1 - traits_type::size()) / traits_type::size())
)
, i_(i >= 0
? i % traits_type::size()
: i % traits_type::size() + traits_type::size()
)
{}
public:
SPROUT_CONSTEXPR bytes_iterator()
: it_()
, i_()
{}
bytes_iterator(bytes_iterator const&) = default;
SPROUT_CONSTEXPR explicit bytes_iterator(base_type it)
: it_(it)
, i_()
{}
SPROUT_CONSTEXPR bytes_iterator next() const {
return bytes_iterator(it_, i_ + 1, next_tag());
}
SPROUT_CONSTEXPR bytes_iterator prev() const {
return bytes_iterator(it_, i_ - 1, prev_tag());
}
void swap(bytes_iterator& other) {
using std::swap;
swap(it_, other.it_);
swap(i_, other.i_);
}
friend SPROUT_CONSTEXPR bool operator==(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return lhs.it_ == rhs.it_ && lhs.i_ == rhs.i_;
}
friend SPROUT_CONSTEXPR bool operator!=(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return !(lhs == rhs);
}
friend bool operator<(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return lhs.it_ < rhs.it_ || lhs.it_ == rhs.it_ && lhs.i_ < rhs.i_;
}
friend bool operator>(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return rhs < lhs;
}
friend bool operator<=(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return !(rhs < lhs);
}
friend bool operator>=(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return !(lhs < rhs);
}
SPROUT_CONSTEXPR reference operator*() const {
return traits_type::get_byte(*it_, i_);
}
bytes_iterator& operator++() {
bytes_iterator temp(next());
temp.swap(*this);
return *this;
}
bytes_iterator operator++(int) {
bytes_iterator result(*this);
++*this;
return result;
}
bytes_iterator& operator--() {
bytes_iterator temp(prev());
temp.swap(*this);
return *this;
}
bytes_iterator operator--(int) {
bytes_iterator result(*this);
--*this;
return result;
}
SPROUT_CONSTEXPR bytes_iterator operator+(difference_type n) const {
return bytes_iterator(it_, i_ + n, ra_tag());
}
SPROUT_CONSTEXPR bytes_iterator operator-(difference_type n) const {
return bytes_iterator(it_, i_ - n, ra_tag());
}
bytes_iterator& operator+=(difference_type n) {
bytes_iterator temp(it_, i_ + n, ra_tag());
temp.swap(this);
return this;
}
bytes_iterator& operator-=(difference_type n) {
bytes_iterator temp(it_, i_ - n, ra_tag());
temp.swap(this);
return this;
}
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return *(*this + n);
}
friend difference_type operator-(bytes_iterator const& lhs, bytes_iterator const& rhs) {
return (lhs.it_ - rhs.it_) * traits_type::size() + (lhs.i_ - rhs.i_);
}
friend SPROUT_CONSTEXPR bytes_iterator operator+(difference_type n, bytes_iterator const& it) {
return it + n;
}
};
//
// swap
//
template<typename Iterator, typename Traits>
inline void swap(sprout::bytes_iterator<Iterator, Traits>& lhs, sprout::bytes_iterator<Iterator, Traits>& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
lhs.swap(rhs);
}
//
// next
//
template<typename Iterator, typename Traits>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator, Traits> next(
sprout::bytes_iterator<Iterator, Traits> const& it
)
{
return it.next();
}
template<typename Iterator, typename Traits>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator, Traits> next(
sprout::bytes_iterator<Iterator, Traits> const& it,
typename sprout::bytes_iterator<Iterator, Traits>::difference_type n
)
{
return it + n;
}
//
// prev
//
template<typename Iterator, typename Traits>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator, Traits> prev(
sprout::bytes_iterator<Iterator, Traits> const& it
)
{
return it.prev();
}
template<typename Iterator, typename Traits>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator, Traits> prev(
sprout::bytes_iterator<Iterator, Traits> const& it,
typename sprout::bytes_iterator<Iterator, Traits>::difference_type n
)
{
return it - n;
}
//
// make_bytes_iterator
//
template<typename Iterator>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator> make_bytes_iterator(Iterator it) {
return sprout::bytes_iterator<Iterator>(it);
}
template<typename Iterator, typename Traits>
SPROUT_CONSTEXPR inline sprout::bytes_iterator<Iterator, Traits> make_bytes_iterator(Iterator it, Traits) {
return sprout::bytes_iterator<Iterator, Traits>(it);
}
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_BYTES_ITERATOR_HPP

View file

@ -1,5 +1,5 @@
#ifndef SPROUT_NULL_ARRAY_HPP
#define SPROUT_NULL_ARRAY_HPP
#ifndef SPROUT_PIT_HPP
#define SPROUT_PIT_HPP
#include <cstddef>
#include <utility>
@ -12,13 +12,13 @@
namespace sprout {
//
// null_array
// pit
//
template<typename Container>
class null_array {
class pit {
public:
typedef Container container_type;
typedef null_array fixed_container_type;
typedef pit fixed_container_type;
typedef container_type internal_type;
typedef typename sprout::fixed_container_traits<internal_type>::clone_type clone_type;
typedef typename sprout::fixed_container_traits<internal_type>::value_type value_type;
@ -38,8 +38,8 @@ namespace sprout {
public:
value_type elem;
public:
null_array() = default;
void swap(null_array& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::swap(std::declval<value_type&>(), std::declval<value_type&>()))) {
pit() = default;
void swap(pit& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::swap(std::declval<value_type&>(), std::declval<value_type&>()))) {
using std::swap;
swap(elem, other.elem);
}
@ -120,14 +120,14 @@ namespace sprout {
// others:
void rangecheck(size_type i) const {
if (i >= size()) {
throw std::out_of_range("null_array<>: index out of range");
throw std::out_of_range("pit<>: index out of range");
}
}
};
template<typename Container>
SPROUT_CONSTEXPR typename sprout::null_array<Container>::size_type sprout::null_array<Container>::static_size;
SPROUT_CONSTEXPR typename sprout::pit<Container>::size_type sprout::pit<Container>::static_size;
template<typename Container>
SPROUT_CONSTEXPR typename sprout::null_array<Container>::size_type sprout::null_array<Container>::fixed_size;
SPROUT_CONSTEXPR typename sprout::pit<Container>::size_type sprout::pit<Container>::fixed_size;
//
// operator==
@ -138,27 +138,27 @@ namespace sprout {
// operator>=
//
template<typename Container>
SPROUT_CONSTEXPR inline bool operator==(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator==(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return lhs.front() == rhs.front();
}
template<typename Container>
SPROUT_CONSTEXPR inline bool operator!=(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator!=(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return !(lhs == rhs);
}
template<typename Container>
SPROUT_CONSTEXPR inline bool operator<(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator<(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return lhs.front() < rhs.front();
}
template<typename Container>
SPROUT_CONSTEXPR inline bool operator>(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator>(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return rhs < lhs;
}
template<typename Container>
SPROUT_CONSTEXPR inline bool operator<=(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator<=(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return !(rhs < lhs);
}
template<typename Container>
SPROUT_CONSTEXPR inline bool operator>=(sprout::null_array<Container> const& lhs, sprout::null_array<Container> const& rhs) {
SPROUT_CONSTEXPR inline bool operator>=(sprout::pit<Container> const& lhs, sprout::pit<Container> const& rhs) {
return !(lhs < rhs);
}
@ -166,7 +166,7 @@ namespace sprout {
// swap
//
template<typename Container>
inline void swap(sprout::null_array<Container>& lhs, sprout::null_array<Container>& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
inline void swap(sprout::pit<Container>& lhs, sprout::pit<Container>& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
lhs.swap(rhs);
}
@ -174,15 +174,15 @@ namespace sprout {
// fixed_container_traits
//
template<typename Container>
struct fixed_container_traits<sprout::null_array<Container> >
: public sprout::detail::fixed_container_traits_base<sprout::null_array<Container> >
struct fixed_container_traits<sprout::pit<Container> >
: public sprout::detail::fixed_container_traits_base<sprout::pit<Container> >
{
public:
typedef typename sprout::null_array<Container>::fixed_container_type fixed_container_type;
typedef typename sprout::null_array<Container>::internal_type internal_type;
typedef typename sprout::null_array<Container>::clone_type clone_type;
typedef typename sprout::pit<Container>::fixed_container_type fixed_container_type;
typedef typename sprout::pit<Container>::internal_type internal_type;
typedef typename sprout::pit<Container>::clone_type clone_type;
public:
SPROUT_STATIC_CONSTEXPR typename sprout::detail::fixed_container_traits_base<sprout::null_array<Container> >::size_type fixed_size
SPROUT_STATIC_CONSTEXPR typename sprout::detail::fixed_container_traits_base<sprout::pit<Container> >::size_type fixed_size
= std::tuple_size<typename std::remove_const<internal_type>::type>::value
;
};
@ -191,14 +191,14 @@ namespace sprout {
// rebind_fixed_size
//
template<typename Container>
struct rebind_fixed_size<sprout::null_array<Container> > {
struct rebind_fixed_size<sprout::pit<Container> > {
public:
template<typename sprout::fixed_container_traits<sprout::null_array<Container> >::size_type S>
template<typename sprout::fixed_container_traits<sprout::pit<Container> >::size_type S>
struct apply {
public:
typedef sprout::null_array<
typedef sprout::pit<
typename sprout::rebind_fixed_size<
typename sprout::fixed_container_traits<sprout::null_array<Container> >::internal_type
typename sprout::fixed_container_traits<sprout::pit<Container> >::internal_type
>::template apply<S>::type
> type;
};
@ -208,14 +208,14 @@ namespace sprout {
// clone_functor
//
template<typename Container>
struct clone_functor<sprout::null_array<Container> > {
struct clone_functor<sprout::pit<Container> > {
private:
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::clone_type clone_type;
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::clone_type clone_type;
public:
clone_type operator()(sprout::null_array<Container>& cont) const {
clone_type operator()(sprout::pit<Container>& cont) const {
return clone_type();
}
SPROUT_CONSTEXPR clone_type operator()(sprout::null_array<Container> const& cont) const {
SPROUT_CONSTEXPR clone_type operator()(sprout::pit<Container> const& cont) const {
return clone_type();
}
};
@ -224,10 +224,10 @@ namespace sprout {
// make_clone_functor
//
template<typename Container>
struct make_clone_functor<sprout::null_array<Container> > {
struct make_clone_functor<sprout::pit<Container> > {
private:
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::clone_type clone_type;
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::internal_type internal_type;
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::clone_type clone_type;
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::internal_type internal_type;
public:
template<typename... Args>
SPROUT_CONSTEXPR clone_type operator()(Args const&... args) const {
@ -239,15 +239,15 @@ namespace sprout {
// remake_clone_functor
//
template<typename Container>
struct remake_clone_functor<sprout::null_array<Container> > {
struct remake_clone_functor<sprout::pit<Container> > {
private:
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::clone_type clone_type;
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::internal_type internal_type;
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::clone_type clone_type;
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::internal_type internal_type;
public:
template<typename Other, typename... Args>
clone_type operator()(
Other& other,
typename sprout::fixed_container_traits<sprout::null_array<Container> >::difference_type size,
typename sprout::fixed_container_traits<sprout::pit<Container> >::difference_type size,
Args const&... args
) const
{
@ -256,7 +256,7 @@ namespace sprout {
template<typename Other, typename... Args>
SPROUT_CONSTEXPR clone_type operator()(
Other const& other,
typename sprout::fixed_container_traits<sprout::null_array<Container> >::difference_type size,
typename sprout::fixed_container_traits<sprout::pit<Container> >::difference_type size,
Args const&... args
) const
{
@ -270,9 +270,9 @@ namespace std {
// tuple_size
//
template<typename Container>
struct tuple_size<sprout::null_array<Container> > {
struct tuple_size<sprout::pit<Container> > {
public:
typedef std::integral_constant<std::size_t, sprout::fixed_container_traits<sprout::null_array<Container> >::fixed_size> type;
typedef std::integral_constant<std::size_t, sprout::fixed_container_traits<sprout::pit<Container> >::fixed_size> type;
SPROUT_STATIC_CONSTEXPR std::size_t value = type::value;
};
@ -280,38 +280,38 @@ namespace std {
// tuple_element
//
template<std::size_t I, typename Container>
struct tuple_element<I, sprout::null_array<Container> > {
struct tuple_element<I, sprout::pit<Container> > {
public:
static_assert(I < sprout::fixed_container_traits<sprout::null_array<Container> >::fixed_size, "tuple_element<>: index out of range");
typedef typename sprout::fixed_container_traits<sprout::null_array<Container> >::value_type type;
static_assert(I < sprout::fixed_container_traits<sprout::pit<Container> >::fixed_size, "tuple_element<>: index out of range");
typedef typename sprout::fixed_container_traits<sprout::pit<Container> >::value_type type;
};
//
// get
//
template<std::size_t I, typename Container>
typename sprout::fixed_container_traits<sprout::null_array<Container> >::value_type& get(
sprout::null_array<Container>& arr
typename sprout::fixed_container_traits<sprout::pit<Container> >::value_type& get(
sprout::pit<Container>& t
) SPROUT_NOEXCEPT
{
static_assert(I < sprout::fixed_container_traits<sprout::null_array<Container> >::fixed_size, "get: index out of range");
return arr[I];
static_assert(I < sprout::fixed_container_traits<sprout::pit<Container> >::fixed_size, "get: index out of range");
return t[I];
}
template<std::size_t I, typename Container>
SPROUT_CONSTEXPR typename sprout::fixed_container_traits<sprout::null_array<Container> >::value_type const& get(
sprout::null_array<Container> const& arr
SPROUT_CONSTEXPR typename sprout::fixed_container_traits<sprout::pit<Container> >::value_type const& get(
sprout::pit<Container> const& t
) SPROUT_NOEXCEPT
{
static_assert(I < sprout::fixed_container_traits<sprout::null_array<Container> >::fixed_size, "get: index out of range");
return arr[I];
static_assert(I < sprout::fixed_container_traits<sprout::pit<Container> >::fixed_size, "get: index out of range");
return t[I];
}
template<std::size_t I, typename Container>
typename sprout::fixed_container_traits<sprout::null_array<Container> >::value_type&& get(
sprout::null_array<Container>&& arr
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::move(std::get<I>(arr))))
typename sprout::fixed_container_traits<sprout::pit<Container> >::value_type&& get(
sprout::pit<Container>&& t
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::move(std::get<I>(t))))
{
return std::move(std::get<I>(arr));
return std::move(std::get<I>(t));
}
} // namespace std
#endif // #ifndef SPROUT_NULL_ARRAY_HPP
#endif // #ifndef SPROUT_PIT_HPP

View file

@ -264,7 +264,7 @@ namespace sprout {
return from_c_str(s, traits_type::length(s));
}
public:
T elems[N + 1];
value_type elems[static_size + 1];
size_type len;
public:
// construct/copy/destroy:
@ -347,7 +347,7 @@ namespace sprout {
return size();
}
SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT {
return N;
return static_size;
}
void resize(size_type n, value_type c) {
maxcheck(n);
@ -1071,18 +1071,18 @@ namespace std {
// get
//
template<std::size_t I, typename T, std::size_t N, typename Traits>
T& get(sprout::basic_string<T, N, Traits>& arr) SPROUT_NOEXCEPT {
T& get(sprout::basic_string<T, N, Traits>& t) SPROUT_NOEXCEPT {
static_assert(I < N, "get: index out of range");
return arr[I];
return t[I];
}
template<std::size_t I, typename T, std::size_t N, typename Traits>
SPROUT_CONSTEXPR T const& get(sprout::basic_string<T, N, Traits> const& arr) SPROUT_NOEXCEPT {
SPROUT_CONSTEXPR T const& get(sprout::basic_string<T, N, Traits> const& t) SPROUT_NOEXCEPT {
static_assert(I < N, "get: index out of range");
return arr[I];
return t[I];
}
template<std::size_t I, typename T, std::size_t N, typename Traits>
T&& get(sprout::basic_string<T, N, Traits>&& arr) SPROUT_NOEXCEPT {
return std::move(std::get<I>(arr));
T&& get(sprout::basic_string<T, N, Traits>&& t) SPROUT_NOEXCEPT {
return std::move(std::get<I>(t));
}
} // namespace std

View file

@ -945,26 +945,26 @@ namespace std {
//
template<std::size_t I, typename Container>
typename sprout::fixed_container_traits<sprout::sub_array<Container> >::value_type& get(
sprout::sub_array<Container>& arr
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::fixed_begin(arr), I)))
sprout::sub_array<Container>& t
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::fixed_begin(t), I)))
{
static_assert(I < sprout::fixed_container_traits<sprout::sub_array<Container> >::fixed_size, "get: index out of range");
return *sprout::next(sprout::fixed_begin(arr), I);
return *sprout::next(sprout::fixed_begin(t), I);
}
template<std::size_t I, typename Container>
SPROUT_CONSTEXPR typename sprout::fixed_container_traits<sprout::sub_array<Container> >::value_type const& get(
sprout::sub_array<Container> const& arr
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::fixed_begin(arr), I)))
sprout::sub_array<Container> const& t
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::fixed_begin(t), I)))
{
static_assert(I < sprout::fixed_container_traits<sprout::sub_array<Container> >::fixed_size, "get: index out of range");
return *sprout::next(sprout::fixed_begin(arr), I);
return *sprout::next(sprout::fixed_begin(t), I);
}
template<std::size_t I, typename Container>
typename sprout::fixed_container_traits<sprout::sub_array<Container> >::value_type&& get(
sprout::sub_array<Container>&& arr
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::move(std::get<I>(arr))))
sprout::sub_array<Container>&& t
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::move(std::get<I>(t))))
{
return std::move(std::get<I>(arr));
return std::move(std::get<I>(t));
}
} // namespace std

10
sprout/uuid.hpp Normal file
View file

@ -0,0 +1,10 @@
#ifndef SPROUT_UUID_HPP
#define SPROUT_UUID_HPP
#include <sprout/config.hpp>
#include <sprout/uuid/uuid.hpp>
#include <sprout/uuid/uuid_io.hpp>
#include <sprout/uuid/uuid_hash.hpp>
#include <sprout/uuid/uuid_generators.hpp>
#endif // #ifndef SPROUT_UUID_HPP

View file

@ -0,0 +1,64 @@
#ifndef SPROUT_UUID_DETAIL_TABLE_HPP
#define SPROUT_UUID_DETAIL_TABLE_HPP
#include <cstdint>
#include <sprout/config.hpp>
#include <sprout/array.hpp>
#include <sprout/string.hpp>
namespace sprout {
namespace uuids {
namespace detail {
template<typename Elem>
struct digits {};
template<>
struct digits<char> {
public:
SPROUT_STATIC_CONSTEXPR sprout::basic_string<char, 22> table = sprout::to_string("0123456789abcdefABCDEF");
SPROUT_STATIC_CONSTEXPR char dash = '-';
};
SPROUT_CONSTEXPR sprout::basic_string<char, 22> sprout::uuids::detail::digits<char>::table;
SPROUT_CONSTEXPR char sprout::uuids::detail::digits<char>::dash;
template<>
struct digits<wchar_t> {
public:
SPROUT_STATIC_CONSTEXPR sprout::basic_string<wchar_t, 22> table = sprout::to_string(L"0123456789abcdefABCDEF");
SPROUT_STATIC_CONSTEXPR wchar_t dash = L'-';
};
SPROUT_CONSTEXPR sprout::basic_string<wchar_t, 22> sprout::uuids::detail::digits<wchar_t>::table;
SPROUT_CONSTEXPR wchar_t sprout::uuids::detail::digits<wchar_t>::dash;
template<>
struct digits<char16_t> {
public:
SPROUT_STATIC_CONSTEXPR sprout::basic_string<char16_t, 22> table = sprout::to_string(u"0123456789abcdefABCDEF");
SPROUT_STATIC_CONSTEXPR char16_t dash = u'-';
};
SPROUT_CONSTEXPR sprout::basic_string<char16_t, 22> sprout::uuids::detail::digits<char16_t>::table;
SPROUT_CONSTEXPR char16_t sprout::uuids::detail::digits<char16_t>::dash;
template<>
struct digits<char32_t> {
public:
SPROUT_STATIC_CONSTEXPR sprout::basic_string<char32_t, 22> table = sprout::to_string(U"0123456789abcdefABCDEF");
SPROUT_STATIC_CONSTEXPR char32_t dash = U'-';
};
SPROUT_CONSTEXPR sprout::basic_string<char32_t, 22> sprout::uuids::detail::digits<char32_t>::table;
SPROUT_CONSTEXPR char32_t sprout::uuids::detail::digits<char32_t>::dash;
template<typename Dummy>
struct values;
template<>
struct values<void> {
public:
SPROUT_STATIC_CONSTEXPR sprout::array<std::uint8_t, 22> table = sprout::array<std::uint8_t, 22>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15}};
};
SPROUT_CONSTEXPR sprout::array<std::uint8_t, 22> sprout::uuids::detail::values<void>::table;
} // namespace detail
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_DETAIL_TABLE_HPP

View file

@ -0,0 +1,72 @@
#ifndef SPROUT_UUID_NAME_GENERATOR_HPP
#define SPROUT_UUID_NAME_GENERATOR_HPP
#include <sprout/config.hpp>
#include <sprout/string.hpp>
#include <sprout/uuid/uuid.hpp>
#include <sprout/checksum/sha1.hpp>
namespace sprout {
namespace uuids {
//
// name_generator
//
class name_generator {
public:
typedef sprout::uuids::uuid result_type;
private:
typedef typename result_type::value_type value_type;
private:
sprout::sha1 sha_;
private:
SPROUT_CONSTEXPR result_type sha_to_uuid_1(sprout::sha1::value_type const& value) const {
return result_type{{
value[0],
value[1],
value[2],
value[3],
value[4],
value[5],
static_cast<value_type>((value[6] & 0x5F) | 0x50),
value[7],
static_cast<value_type>((value[8] & 0xBF) | 0x80),
value[9],
value[10],
value[11],
value[12],
value[13],
value[14],
value[15]
}};
}
SPROUT_CONSTEXPR result_type sha_to_uuid(sprout::sha1 const& sha) const {
return sha_to_uuid_1(sha.checksum());
}
public:
SPROUT_CONSTEXPR name_generator()
: sha_(sprout::sha1().process_range(sprout::uuids::uuid{{0}}))
{}
SPROUT_CONSTEXPR explicit name_generator(sprout::uuids::uuid const& namespace_uuid)
: sha_(sprout::sha1().process_range(namespace_uuid))
{}
template<typename Elem, std::size_t N, typename Traits>
SPROUT_CONSTEXPR result_type operator()(sprout::basic_string<Elem, N, Traits> const& name) const {
return sha_to_uuid(sha_.process_range(name));
}
SPROUT_CONSTEXPR result_type operator()(char const* name) const {
return sha_to_uuid(sha_.process_bytes(name, sprout::char_traits<char>::length(name)));
}
SPROUT_CONSTEXPR result_type operator()(wchar_t const* name) const {
return sha_to_uuid(sha_.process_bytes(name, sprout::char_traits<wchar_t>::length(name)));
}
SPROUT_CONSTEXPR result_type operator()(char16_t const* name) const {
return sha_to_uuid(sha_.process_bytes(name, sprout::char_traits<char16_t>::length(name)));
}
SPROUT_CONSTEXPR result_type operator()(char32_t const* name) const {
return sha_to_uuid(sha_.process_bytes(name, sprout::char_traits<char32_t>::length(name)));
}
};
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_NAME_GENERATOR_HPP

View file

@ -0,0 +1,29 @@
#ifndef SPROUT_UUID_NIL_GENERATOR_HPP
#define SPROUT_UUID_NIL_GENERATOR_HPP
#include <sprout/config.hpp>
#include <sprout/uuid/uuid.hpp>
namespace sprout {
namespace uuids {
//
// nil_generator
//
class nil_generator {
public:
typedef sprout::uuids::uuid result_type;
public:
SPROUT_CONSTEXPR result_type operator()() const {
return result_type{{0}};
}
};
//
// nil_uuid
//
SPROUT_CONSTEXPR inline sprout::uuids::uuid nil_uuid() {
return sprout::uuids::nil_generator()();
}
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_NIL_GENERATOR_HPP

View file

@ -0,0 +1,90 @@
#ifndef SPROUT_UUID_RANDOM_GENERATOR_HPP
#define SPROUT_UUID_RANDOM_GENERATOR_HPP
#include <cstdint>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/uuid/uuid.hpp>
#include <sprout/random/inversive_congruential.hpp>
#include <sprout/random/uniform_int_distribution.hpp>
#include <sprout/random/variate_generator.hpp>
namespace sprout {
namespace uuids {
//
// basic_random_generator
//
template<typename UniformRandomNumberGenerator>
class basic_random_generator {
public:
typedef sprout::uuids::uuid result_type;
private:
typedef UniformRandomNumberGenerator engine_type;
typedef sprout::random::uniform_int_distribution<std::uint32_t> distribution_type;
typedef typename result_type::value_type value_type;
private:
distribution_type distribution_;
private:
SPROUT_CONSTEXPR result_type random_to_uuid_1(std::uint32_t v0, std::uint32_t v1, std::uint32_t v2, std::uint32_t v3) const {
return result_type{{
static_cast<value_type>((v0 >> 24) & 0xFF),
static_cast<value_type>((v0 >> 16) & 0xFF),
static_cast<value_type>((v0 >> 8) & 0xFF),
static_cast<value_type>((v0) & 0xFF),
static_cast<value_type>((v1 >> 24) & 0xFF),
static_cast<value_type>((v1 >> 16) & 0xFF),
static_cast<value_type>(((v1 >> 8) & 0x4F) | 0x40),
static_cast<value_type>((v1) & 0xFF),
static_cast<value_type>(((v2 >> 24) & 0xBF) | 0x80),
static_cast<value_type>((v2 >> 16) & 0xFF),
static_cast<value_type>((v2 >> 8) & 0xFF),
static_cast<value_type>((v2) & 0xFF),
static_cast<value_type>((v3 >> 24) & 0xFF),
static_cast<value_type>((v3 >> 16) & 0xFF),
static_cast<value_type>((v3 >> 8) & 0xFF),
static_cast<value_type>((v3) & 0xFF)
}};
}
template<typename Random, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 3,
result_type
>::type random_to_uuid(Random const& rnd, Args... args) const {
return random_to_uuid_1(args..., rnd.result());
}
template<typename Random, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) != 3,
result_type
>::type random_to_uuid(Random const& rnd, Args... args) const {
return random_to_uuid(rnd(), args..., rnd.result());
}
public:
SPROUT_CONSTEXPR basic_random_generator()
: distribution_(std::numeric_limits<std::uint32_t>::min(), std::numeric_limits<std::uint32_t>::max())
{}
template<typename T>
SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
result_type
>::type operator()(T const& seed) const {
return operator()(engine_type(seed));
}
template<typename Engine>
SPROUT_CONSTEXPR typename std::enable_if<
!std::is_integral<Engine>::value,
result_type
>::type operator()(Engine const& engine) const {
return random_to_uuid(sprout::random::combine(engine, distribution_)());
}
};
//
// random_generator
//
typedef sprout::uuids::basic_random_generator<sprout::random::hellekalek1995> random_generator;
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_RANDOM_GENERATOR_HPP

View file

@ -0,0 +1,191 @@
#ifndef SPROUT_UUID_STRING_GENERATOR_HPP
#define SPROUT_UUID_STRING_GENERATOR_HPP
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/string.hpp>
#include <sprout/uuid/uuid.hpp>
#include <sprout/uuid/detail/table.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT_DETAIL
namespace sprout {
namespace uuids {
//
// string_generator
//
class string_generator {
public:
typedef sprout::uuids::uuid result_type;
private:
template<typename Iterator>
struct next_char {
public:
typedef typename std::iterator_traits<Iterator>::value_type char_type;
public:
char_type c;
Iterator first;
Iterator last;
public:
SPROUT_CONSTEXPR next_char(Iterator f, Iterator l)
: c(f != l ? *f : throw "string_generator: invalid uuid string (out of range)")
, first(sprout::next(f))
, last(l)
{}
SPROUT_CONSTEXPR next_char next() const {
return next_char(first, last);
}
};
private:
SPROUT_CONSTEXPR std::uint8_t value_at(std::size_t i) const {
return i < 22
? sprout::uuids::detail::values<void>::table[i]
: throw "string_generator: invalid uuid string (invalid character)"
;
}
template<typename Elem>
SPROUT_CONSTEXPR std::uint8_t get_value(Elem c) const {
return value_at(
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::distance(
sprout::uuids::detail::digits<Elem>::table.begin(),
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::find(
sprout::uuids::detail::digits<Elem>::table.begin(),
sprout::uuids::detail::digits<Elem>::table.end(),
c
)
)
);
}
static SPROUT_CONSTEXPR bool is_dash(char c) {
return c == '-';
}
static SPROUT_CONSTEXPR bool is_dash(wchar_t c) {
return c == L'-';
}
static SPROUT_CONSTEXPR bool is_dash(char16_t c) {
return c == u'-';
}
static SPROUT_CONSTEXPR bool is_dash(char32_t c) {
return c == U'-';
}
static SPROUT_CONSTEXPR bool is_open_brace(char c) {
return c == '{';
}
static SPROUT_CONSTEXPR bool is_open_brace(wchar_t c) {
return c == L'{';
}
static SPROUT_CONSTEXPR bool is_open_brace(char16_t c) {
return c == u'{';
}
static SPROUT_CONSTEXPR bool is_open_brace(char32_t c) {
return c == U'{';
}
static SPROUT_CONSTEXPR bool is_close_brace(char c, char open_brace) {
return open_brace == '{' && c == '}';
}
static SPROUT_CONSTEXPR bool is_close_brace(wchar_t c, char open_brace) {
return open_brace == L'{' && c == L'}';
}
static SPROUT_CONSTEXPR bool is_close_brace(char16_t c, char open_brace) {
return open_brace == u'{' && c == u'}';
}
static SPROUT_CONSTEXPR bool is_close_brace(char32_t c, char open_brace) {
return open_brace == U'{' && c == U'}';
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR result_type generate_2_3(next_char<Iterator> nc, Char open_brace, bool has_dashes, std::uint8_t byte, Args... args) const {
return generate_2(nc, open_brace, has_dashes, args..., static_cast<std::uint8_t>((byte << 4) | get_value(nc.c)));
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR result_type generate_2_2(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return generate_2_3(nc.next(), open_brace, has_dashes, get_value(nc.c), args...);
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 6 || sizeof...(Args) == 8 || sizeof...(Args) == 10,
result_type
>::type generate_2_1(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return has_dashes
? is_dash(nc.c)
? generate_2_2(nc.next(), open_brace, has_dashes, args...)
//: throw "string_generator: invalid uuid string (dashes not found)" // ???
: generate_2_2(nc, open_brace, has_dashes, args...)
: generate_2_2(nc, open_brace, has_dashes, args...)
;
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 4,
result_type
>::type generate_2_1(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return is_dash(nc.c)
? generate_2_2(nc.next(), open_brace, true, args...)
: generate_2_2(nc, open_brace, false, args...)
;
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) != 4 && sizeof...(Args) != 6 && sizeof...(Args) != 8 && sizeof...(Args) != 10,
result_type
>::type generate_2_1(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return generate_2_2(nc, open_brace, has_dashes, args...);
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 16,
result_type
>::type generate_2(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return !open_brace || (open_brace && is_close_brace(nc.next().c, open_brace))
? result_type{{args...}}
: throw "string_generator: invalid uuid string (brace not closed)"
;
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == 0,
result_type
>::type generate_2(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return generate_2_2(nc, open_brace, has_dashes, args...);
}
template<typename Iterator, typename Char, typename... Args>
SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) != 0 && sizeof...(Args) != 16,
result_type
>::type generate_2(next_char<Iterator> nc, Char open_brace, bool has_dashes, Args... args) const {
return generate_2_1(nc.next(), open_brace, has_dashes, args...);
}
template<typename Iterator>
SPROUT_CONSTEXPR result_type generate_1(next_char<Iterator> nc) const {
return is_open_brace(nc.c)
? generate_2(nc.next(), nc.c, false)
: generate_2(nc, typename next_char<Iterator>::char_type(), false)
;
}
public:
template<typename Elem, std::size_t N, typename Traits>
SPROUT_CONSTEXPR result_type operator()(sprout::basic_string<Elem, N, Traits> const& s) const {
return operator()(s.begin(), s.end());
}
SPROUT_CONSTEXPR result_type operator()(char const* s) const {
return operator()(s, s + sprout::char_traits<char>::length(s));
}
SPROUT_CONSTEXPR result_type operator()(wchar_t const* s) const {
return operator()(s, s + sprout::char_traits<wchar_t>::length(s));
}
SPROUT_CONSTEXPR result_type operator()(char16_t const* s) const {
return operator()(s, s + sprout::char_traits<char16_t>::length(s));
}
SPROUT_CONSTEXPR result_type operator()(char32_t const* s) const {
return operator()(s, s + sprout::char_traits<char32_t>::length(s));
}
template<typename Iterator>
SPROUT_CONSTEXPR result_type operator()(Iterator first, Iterator last) const {
return generate_1(next_char<Iterator>(first, last));
}
};
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_STRING_GENERATOR_HPP

299
sprout/uuid/uuid.hpp Normal file
View file

@ -0,0 +1,299 @@
#ifndef SPROUT_UUID_UUID_HPP
#define SPROUT_UUID_UUID_HPP
#include <cstddef>
#include <algorithm>
#include <utility>
#include <stdexcept>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/iterator.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
# include <sprout/iterator/index_iterator.hpp>
#endif
namespace sprout {
namespace uuids {
namespace detail {
template<typename InputIterator>
SPROUT_CONSTEXPR inline bool is_nil(InputIterator first, InputIterator last) {
return first == last ? true
: !*first && sprout::uuids::detail::is_nil(sprout::next(first), last)
;
}
} // namespace detail
//
// uuid
//
class uuid {
public:
typedef std::uint8_t value_type;
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
typedef sprout::index_iterator<uuid&> iterator;
typedef sprout::index_iterator<uuid const&> const_iterator;
#else
typedef std::uint8_t* iterator;
typedef std::uint8_t const* const_iterator;
#endif
typedef std::uint8_t& reference;
typedef std::uint8_t const& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::uint8_t* pointer;
typedef std::uint8_t const* const_pointer;
typedef sprout::reverse_iterator<iterator> reverse_iterator;
typedef sprout::reverse_iterator<const_iterator> const_reverse_iterator;
public:
//
// variant_type
//
enum variant_type {
variant_ncs,
variant_rfc_4122,
variant_microsoft,
variant_future
};
//
// version_type
//
enum version_type {
version_unknown = -1,
version_time_based = 1,
version_dce_security = 2,
version_name_based_md5 = 3,
version_random_number_based = 4,
version_name_based_sha1 = 5
};
public:
SPROUT_STATIC_CONSTEXPR size_type static_size = 16;
SPROUT_STATIC_CONSTEXPR size_type fixed_size = static_size;
public:
value_type elems[static_size];
public:
void fill(const_reference value) {
std::fill_n(begin(), size(), value);
}
void swap(uuid& other) SPROUT_NOEXCEPT {
std::swap_ranges(other.begin(), other.end(), begin());
}
// iterators:
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
iterator begin() SPROUT_NOEXCEPT {
return iterator(*this, 0);
}
SPROUT_CONSTEXPR const_iterator begin() const SPROUT_NOEXCEPT {
return const_iterator(*this, 0);
}
iterator end() SPROUT_NOEXCEPT {
return iterator(*this, size());
}
SPROUT_CONSTEXPR const_iterator end() const SPROUT_NOEXCEPT {
return const_iterator(*this, size());
}
#else
iterator begin() SPROUT_NOEXCEPT {
return &elems[0];
}
SPROUT_CONSTEXPR const_iterator begin() const SPROUT_NOEXCEPT {
return &elems[0];
}
iterator end() SPROUT_NOEXCEPT {
return &elems[0] + size();
}
SPROUT_CONSTEXPR const_iterator end() const SPROUT_NOEXCEPT {
return &elems[0] + size();
}
#endif
reverse_iterator rbegin() SPROUT_NOEXCEPT {
return reverse_iterator(end());
}
SPROUT_CONSTEXPR const_reverse_iterator rbegin() const SPROUT_NOEXCEPT {
return const_reverse_iterator(end());
}
reverse_iterator rend() SPROUT_NOEXCEPT {
return reverse_iterator(begin());
}
SPROUT_CONSTEXPR const_reverse_iterator rend() const SPROUT_NOEXCEPT {
return const_reverse_iterator(begin());
}
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT {
return const_iterator(*this, 0);
}
SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT {
return const_iterator(*this, size());
}
#else
SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT {
return &elems[0];
}
SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT {
return &elems[0] + size();
}
#endif
SPROUT_CONSTEXPR const_reverse_iterator crbegin() const SPROUT_NOEXCEPT {
return const_reverse_iterator(end());
}
SPROUT_CONSTEXPR const_reverse_iterator crend() const SPROUT_NOEXCEPT {
return const_reverse_iterator(begin());
}
// capacity:
SPROUT_CONSTEXPR size_type size() const SPROUT_NOEXCEPT {
return static_size;
}
SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT {
return size();
}
SPROUT_CONSTEXPR bool empty() const SPROUT_NOEXCEPT {
return size() == 0;
}
// element access:
reference operator[](size_type i) {
return elems[i];
}
SPROUT_CONSTEXPR const_reference operator[](size_type i) const {
return elems[i];
}
reference at(size_type i) {
rangecheck(i);
return elems[i];
}
const_reference at(size_type i) const {
rangecheck(i);
return elems[i];
}
reference front() {
return elems[0];
}
SPROUT_CONSTEXPR const_reference front() const {
return elems[0];
}
reference back() {
return elems[size() - 1];
}
SPROUT_CONSTEXPR const_reference back() const {
return elems[size() - 1];
}
pointer data() SPROUT_NOEXCEPT {
return &elems[0];
}
SPROUT_CONSTEXPR const_pointer data() const SPROUT_NOEXCEPT {
return &elems[0];
}
// others:
pointer c_array() SPROUT_NOEXCEPT {
return &elems[0];
}
void assign(const_reference value) {
fill(value);
}
void rangecheck(size_type i) const {
if (i >= size()) {
throw std::out_of_range("uuid<>: index out of range");
}
}
SPROUT_CONSTEXPR bool is_nil() const {
return sprout::uuids::detail::is_nil(begin(), end());
}
SPROUT_CONSTEXPR variant_type variant() const {
return (elems[8] & 0x80) == 0x00 ? variant_ncs
: (elems[8] & 0xC0) == 0x80 ? variant_rfc_4122
: (elems[8] & 0xE0) == 0xC0 ? variant_microsoft
: variant_future
;
}
SPROUT_CONSTEXPR version_type version() const {
return (elems[6] & 0xF0) == 0x10 ? version_time_based
: (elems[6] & 0xF0) == 0x20 ? version_dce_security
: (elems[6] & 0xF0) == 0x30 ? version_name_based_md5
: (elems[6] & 0xF0) == 0x40 ? version_random_number_based
: (elems[6] & 0xF0) == 0x50 ? version_name_based_sha1
: version_unknown
;
}
};
//
// operator==
// operator!=
// operator<
// operator>
// operator<=
// operator>=
//
SPROUT_CONSTEXPR inline bool operator==(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return NS_SSCRISK_CEL_OR_SPROUT_DETAIL::equal(lhs.begin(), lhs.end(), rhs.begin());
}
SPROUT_CONSTEXPR inline bool operator!=(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return !(lhs == rhs);
}
SPROUT_CONSTEXPR inline bool operator<(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return NS_SSCRISK_CEL_OR_SPROUT_DETAIL::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
SPROUT_CONSTEXPR inline bool operator>(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return rhs < lhs;
}
SPROUT_CONSTEXPR inline bool operator<=(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return !(rhs < lhs);
}
SPROUT_CONSTEXPR inline bool operator>=(sprout::uuids::uuid const& lhs, sprout::uuids::uuid const& rhs) {
return !(lhs < rhs);
}
//
// swap
//
inline void swap(sprout::uuids::uuid& lhs, sprout::uuids::uuid& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
lhs.swap(rhs);
}
} // namespace uuids
using sprout::uuids::uuid;
} // namespace sprout
namespace std {
//
// tuple_size
//
template<>
struct tuple_size<sprout::uuids::uuid> {
public:
typedef std::integral_constant<std::size_t, 16> type;
SPROUT_STATIC_CONSTEXPR std::size_t value = type::value;
};
//
// tuple_element
//
template<std::size_t I>
struct tuple_element<I, sprout::uuids::uuid> {
public:
static_assert(I < 16, "tuple_element<>: index out of range");
typedef sprout::uuids::uuid::value_type type;
};
//
// get
//
template<std::size_t I>
sprout::uuids::uuid::value_type& get(sprout::uuids::uuid& t) SPROUT_NOEXCEPT {
static_assert(I < 16, "get: index out of range");
return t[I];
}
template<std::size_t I>
SPROUT_CONSTEXPR sprout::uuids::uuid::value_type const& get(sprout::uuids::uuid const& t) SPROUT_NOEXCEPT {
static_assert(I < 16, "get: index out of range");
return t[I];
}
template<std::size_t I>
sprout::uuids::uuid::value_type&& get(sprout::uuids::uuid&& t) SPROUT_NOEXCEPT {
return std::move(std::get<I>(t));
}
} // namespace std
#endif // #ifndef SPROUT_UUID_UUID_HPP

View file

@ -0,0 +1,10 @@
#ifndef SPROUT_UUID_UUID_GENERATORS_HPP
#define SPROUT_UUID_UUID_GENERATORS_HPP
#include <sprout/config.hpp>
#include <sprout/uuid/nil_generator.hpp>
#include <sprout/uuid/string_generator.hpp>
#include <sprout/uuid/name_generator.hpp>
#include <sprout/uuid/random_generator.hpp>
#endif // #ifndef SPROUT_UUID_UUID_GENERATORS_HPP

14
sprout/uuid/uuid_hash.hpp Normal file
View file

@ -0,0 +1,14 @@
#ifndef SPROUT_UUID_UUID_HASH_HPP
#define SPROUT_UUID_UUID_HASH_HPP
#include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp>
#include <sprout/uuid/uuid.hpp>
namespace sprout {
SPROUT_CONSTEXPR std::size_t hash_value(sprout::uuids::uuid const& v) {
return sprout::hash_range(v.begin(), v.end());
}
} // namespace sprout
#endif // #ifndef SPROUT_UUID_UUID_HASH_HPP

184
sprout/uuid/uuid_io.hpp Normal file
View file

@ -0,0 +1,184 @@
#ifndef SPROUT_UUID_UUID_IO_HPP
#define SPROUT_UUID_UUID_IO_HPP
#include <cstddef>
#include <algorithm>
#include <iterator>
#include <ios>
#include <ostream>
#include <istream>
#include <locale>
#include <sprout/config.hpp>
#include <sprout/string.hpp>
#include <sprout/uuid/uuid.hpp>
#include <sprout/uuid/detail/table.hpp>
#include <sprout/detail/io/ios_state.hpp>
namespace sprout {
namespace uuids {
//
// operator>>
//
template<typename Elem, typename Traits>
std::basic_istream<Elem, Traits>& operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::uuids::uuid& rhs) {
typedef typename std::basic_ios<Elem, Traits>::char_type char_type;
typename std::basic_istream<Elem, Traits>::sentry const ok(lhs);
typedef std::ctype<Elem> ctype_type;
if (ok) {
sprout::uuids::uuid::value_type data[16];
ctype_type const& ctype = std::use_facet<ctype_type>(lhs.getloc());
char_type xdigits[16];
{
char const szdigits[] = "0123456789ABCDEF";
ctype.widen(szdigits, szdigits + 16, xdigits);
}
char_type const* const xdigits_end = xdigits + 16;
char_type c;
for (sprout::uuids::uuid::size_type i = 0, last = rhs.size(); i < last && lhs; ++i) {
lhs >> c;
c = ctype.toupper(c);
char_type const* f = std::find(xdigits, xdigits_end, c);
if (f == xdigits_end) {
lhs.setstate(std::ios_base::failbit);
break;
}
sprout::uuids::uuid::value_type byte = static_cast<sprout::uuids::uuid::value_type>(std::distance(&xdigits[0], f));
lhs >> c;
c = ctype.toupper(c);
f = std::find(xdigits, xdigits_end, c);
if (f == xdigits_end) {
lhs.setstate(std::ios_base::failbit);
break;
}
byte <<= 4;
byte |= static_cast<sprout::uuids::uuid::value_type>(std::distance(&xdigits[0], f));
data[i] = byte;
if (lhs) {
if (i == 3 || i == 5 || i == 7 || i == 9) {
lhs >> c;
if (c != lhs.widen('-')) {
lhs.setstate(std::ios_base::failbit);
break;
}
}
}
}
if (lhs) {
std::copy(data, data + 16, rhs.begin());
}
}
return lhs;
}
//
// operator<<
//
template<typename Elem, typename Traits>
std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& lhs, sprout::uuids::uuid const& rhs) {
sprout::detail::io::ios_flags_saver flags_saver(lhs);
sprout::detail::io::basic_ios_fill_saver<Elem, Traits> fill_saver(lhs);
typename std::basic_ostream<Elem, Traits>::sentry const ok(lhs);
if (ok) {
std::streamsize const width = lhs.width(0);
std::streamsize const uuid_width = 36;
std::ios_base::fmtflags const flags = lhs.flags();
typename std::basic_ios<Elem, Traits>::char_type const fill = lhs.fill();
if (flags & (std::ios_base::right | std::ios_base::internal)) {
for (std::streamsize i = uuid_width; i < width; ++i) {
lhs << fill;
}
}
lhs << std::hex;
lhs.fill(lhs.widen('0'));
std::size_t i = 0;
for (sprout::uuids::uuid::const_iterator i_data = rhs.begin(), i_last = rhs.end(); i_data != i_last; ++i_data, ++i) {
lhs.width(2);
lhs << static_cast<unsigned>(*i_data);
if (i == 3 || i == 5 || i == 7 || i == 9) {
lhs << lhs.widen('-');
}
}
if (flags & std::ios_base::left) {
for (std::streamsize i = uuid_width; i < width; ++i) {
lhs << fill;
}
}
lhs.width(0);
}
return lhs;
}
//
// to_string_of
//
template<typename Elem, typename Traits = sprout::char_traits<Elem> >
SPROUT_CONSTEXPR inline sprout::basic_string<Elem, 36, Traits> to_string_of(sprout::uuids::uuid const& u) {
return sprout::basic_string<Elem, 36, Traits>{
{
sprout::uuids::detail::digits<Elem>::table[(u[0] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[0]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[1] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[1]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[2] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[2]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[3] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[3]) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[4] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[4]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[5] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[5]) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[6] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[6]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[7] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[7]) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[8] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[8]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[9] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[9]) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[10] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[10]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[11] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[11]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[12] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[12]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[13] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[13]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[14] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[14]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[15] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[15]) & 0x0F]
},
36
};
}
//
// to_string
//
SPROUT_CONSTEXPR inline sprout::basic_string<char, 36> to_string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char>(u);
}
//
// to_wstring
//
SPROUT_CONSTEXPR inline sprout::basic_string<wchar_t, 36> to_wstring(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<wchar_t>(u);
}
//
// to_u16string
//
SPROUT_CONSTEXPR inline sprout::basic_string<char16_t, 36> to_u16string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char16_t>(u);
}
//
// to_u32string
//
SPROUT_CONSTEXPR inline sprout::basic_string<char32_t, 36> to_u32string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char32_t>(u);
}
} // namespace uuids
} // namespace sprout
#endif // #ifndef SPROUT_UUID_UUID_IO_HPP