1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-07-02 14:04:09 +00:00

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

@ -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