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:
parent
9074c9a1cf
commit
0f8db75fca
22 changed files with 2126 additions and 86 deletions
64
sprout/uuid/detail/table.hpp
Normal file
64
sprout/uuid/detail/table.hpp
Normal 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
|
72
sprout/uuid/name_generator.hpp
Normal file
72
sprout/uuid/name_generator.hpp
Normal 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
|
29
sprout/uuid/nil_generator.hpp
Normal file
29
sprout/uuid/nil_generator.hpp
Normal 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
|
90
sprout/uuid/random_generator.hpp
Normal file
90
sprout/uuid/random_generator.hpp
Normal 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
|
191
sprout/uuid/string_generator.hpp
Normal file
191
sprout/uuid/string_generator.hpp
Normal 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
299
sprout/uuid/uuid.hpp
Normal 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
|
10
sprout/uuid/uuid_generators.hpp
Normal file
10
sprout/uuid/uuid_generators.hpp
Normal 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
14
sprout/uuid/uuid_hash.hpp
Normal 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
184
sprout/uuid/uuid_io.hpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue