mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 08:31:03 +08:00
Move chrono_io.h functionality into date.h.
This commit is contained in:
parent
05db422ca9
commit
d15491103b
@ -17,13 +17,11 @@ This is actually several separate C++11/C++14 libraries:
|
|||||||
|
|
||||||
Here are the Cppcon 2016 slides on tz.h: http://schd.ws/hosted_files/cppcon2016/0f/Welcome%20To%20The%20Time%20Zone%20-%20Howard%20Hinnant%20-%20CppCon%202016.pdf
|
Here are the Cppcon 2016 slides on tz.h: http://schd.ws/hosted_files/cppcon2016/0f/Welcome%20To%20The%20Time%20Zone%20-%20Howard%20Hinnant%20-%20CppCon%202016.pdf
|
||||||
|
|
||||||
3. `"chrono_io.h"` is a header-only library for streaming out chrono durations. See http://howardhinnant.github.io/date/chrono_io.html for more details.
|
3. `"iso_week.h"` is a header-only library built on top of the `"date.h"` library which implements the ISO week date calendar. See http://howardhinnant.github.io/date/iso_week.html for more details.
|
||||||
|
|
||||||
4. `"iso_week.h"` is a header-only library built on top of the `"date.h"` library which implements the ISO week date calendar. See http://howardhinnant.github.io/date/iso_week.html for more details.
|
4. `"julian.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Julian calendar which is fully interoperable with everything above. See http://howardhinnant.github.io/date/julian.html for more details.
|
||||||
|
|
||||||
5. `"julian.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Julian calendar which is fully interoperable with everything above. See http://howardhinnant.github.io/date/julian.html for more details.
|
5. `"islamic.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Islamic calendar which is fully interoperable with everything above. See http://howardhinnant.github.io/date/islamic.html for more details.
|
||||||
|
|
||||||
6. `"islamic.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Islamic calendar which is fully interoperable with everything above. See http://howardhinnant.github.io/date/islamic.html for more details.
|
|
||||||
|
|
||||||
There has been a recent change in the library design. If you are trying to migrate from the previous design, rename `day_point` to `sys_days` everywhere, and that ought to bring the number of errors down to a small roar.
|
There has been a recent change in the library design. If you are trying to migrate from the previous design, rename `day_point` to `sys_days` everywhere, and that ought to bring the number of errors down to a small roar.
|
||||||
|
|
||||||
|
647
chrono_io.h
647
chrono_io.h
@ -27,651 +27,8 @@
|
|||||||
// been invented (that would involve another several millennia of evolution).
|
// been invented (that would involve another several millennia of evolution).
|
||||||
// We did not mean to shout.
|
// We did not mean to shout.
|
||||||
|
|
||||||
#include <chrono>
|
// This functionality has moved to "date.h"
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <ratio>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace date
|
#include "date.h"
|
||||||
{
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
#if __cplusplus >= 201402
|
|
||||||
|
|
||||||
template <class CharT, std::size_t N>
|
|
||||||
class string_literal
|
|
||||||
{
|
|
||||||
CharT p_[N];
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_iterator = const CharT*;
|
|
||||||
|
|
||||||
string_literal(string_literal const&) = default;
|
|
||||||
string_literal& operator=(string_literal const&) = delete;
|
|
||||||
|
|
||||||
template <std::size_t N1 = 2,
|
|
||||||
class = std::enable_if_t<N1 == N>>
|
|
||||||
constexpr string_literal(CharT c) noexcept
|
|
||||||
: p_{c}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr string_literal(const CharT(&a)[N]) noexcept
|
|
||||||
: p_{}
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
|
||||||
p_[i] = a[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U = CharT, class = std::enable_if_t<1 < sizeof(U)>>
|
|
||||||
constexpr string_literal(const char(&a)[N]) noexcept
|
|
||||||
: p_{}
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
|
||||||
p_[i] = a[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT2, class = std::enable_if_t<!std::is_same<CharT2, CharT>{}>>
|
|
||||||
constexpr string_literal(string_literal<CharT2, N> const& a) noexcept
|
|
||||||
: p_{}
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
|
||||||
p_[i] = a[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t N1, std::size_t N2,
|
|
||||||
class = std::enable_if_t<N1 + N2 - 1 == N>>
|
|
||||||
constexpr string_literal(const string_literal<CharT, N1>& x,
|
|
||||||
const string_literal<CharT, N2>& y) noexcept
|
|
||||||
: p_{}
|
|
||||||
{
|
|
||||||
std::size_t i = 0;
|
|
||||||
for (; i < N1-1; ++i)
|
|
||||||
p_[i] = x[i];
|
|
||||||
for (std::size_t j = 0; j < N2; ++j, ++i)
|
|
||||||
p_[i] = y[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const CharT* data() const noexcept {return p_;}
|
|
||||||
constexpr std::size_t size() const noexcept {return N-1;}
|
|
||||||
|
|
||||||
constexpr const_iterator begin() const noexcept {return p_;}
|
|
||||||
constexpr const_iterator end() const noexcept {return p_ + N-1;}
|
|
||||||
|
|
||||||
constexpr CharT const& operator[](std::size_t n) const noexcept
|
|
||||||
{
|
|
||||||
return p_[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Traits>
|
|
||||||
friend
|
|
||||||
std::basic_ostream<CharT, Traits>&
|
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s)
|
|
||||||
{
|
|
||||||
return os << s.p_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
string_literal<std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>,
|
|
||||||
N1 + N2 - 1>
|
|
||||||
operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) noexcept
|
|
||||||
{
|
|
||||||
using CharT = std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>;
|
|
||||||
return string_literal<CharT, N1 + N2 - 1>{string_literal<CharT, N1>{x},
|
|
||||||
string_literal<CharT, N2>{y}};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Alloc, std::size_t N>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT, Traits, Alloc>
|
|
||||||
operator+(std::basic_string<CharT, Traits, Alloc> x,
|
|
||||||
const string_literal<CharT, N>& y) noexcept
|
|
||||||
{
|
|
||||||
x.append(y.data(), y.size());
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, std::size_t N>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
string_literal<CharT, N>
|
|
||||||
msl(const CharT(&a)[N]) noexcept
|
|
||||||
{
|
|
||||||
return string_literal<CharT, N>{a};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT,
|
|
||||||
class = std::enable_if_t<std::is_same<CharT, char>{} ||
|
|
||||||
std::is_same<CharT, wchar_t>{} ||
|
|
||||||
std::is_same<CharT, char16_t>{} ||
|
|
||||||
std::is_same<CharT, char32_t>{}>>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
string_literal<CharT, 2>
|
|
||||||
msl(CharT c) noexcept
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 2>{c};
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr
|
|
||||||
std::size_t
|
|
||||||
to_string_len(std::intmax_t i)
|
|
||||||
{
|
|
||||||
std::size_t r = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
i /= 10;
|
|
||||||
++r;
|
|
||||||
} while (i > 0);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::intmax_t N>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
N < 10,
|
|
||||||
string_literal<char, to_string_len(N)+1>
|
|
||||||
>
|
|
||||||
msl() noexcept
|
|
||||||
{
|
|
||||||
return msl(char(N % 10 + '0'));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::intmax_t N>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
10 <= N,
|
|
||||||
string_literal<char, to_string_len(N)+1>
|
|
||||||
>
|
|
||||||
msl() noexcept
|
|
||||||
{
|
|
||||||
return msl<N/10>() + msl(char(N % 10 + '0'));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, std::intmax_t N, std::intmax_t D>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
std::ratio<N, D>::type::den != 1,
|
|
||||||
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) +
|
|
||||||
to_string_len(std::ratio<N, D>::type::den) + 4>
|
|
||||||
>
|
|
||||||
msl(std::ratio<N, D>) noexcept
|
|
||||||
{
|
|
||||||
using R = typename std::ratio<N, D>::type;
|
|
||||||
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) +
|
|
||||||
msl<R::den>() + msl(CharT{']'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, std::intmax_t N, std::intmax_t D>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
std::ratio<N, D>::type::den == 1,
|
|
||||||
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3>
|
|
||||||
>
|
|
||||||
msl(std::ratio<N, D>) noexcept
|
|
||||||
{
|
|
||||||
using R = typename std::ratio<N, D>::type;
|
|
||||||
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::atto) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'a'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::femto) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'f'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::pico) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'p'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::nano) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'n'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
std::is_same<CharT, char>{},
|
|
||||||
string_literal<char, 3>
|
|
||||||
>
|
|
||||||
msl(std::micro) noexcept
|
|
||||||
{
|
|
||||||
return string_literal<char, 3>{"\xC2\xB5"};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::enable_if_t
|
|
||||||
<
|
|
||||||
!std::is_same<CharT, char>{},
|
|
||||||
string_literal<CharT, 2>
|
|
||||||
>
|
|
||||||
msl(std::micro) noexcept
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::milli) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'m'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::centi) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'c'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::deci) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'d'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::deca) noexcept
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 3>{"da"};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::hecto) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'h'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::kilo) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'k'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::mega) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'M'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::giga) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'G'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::tera) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'T'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::peta) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'P'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
auto
|
|
||||||
msl(std::exa) noexcept
|
|
||||||
{
|
|
||||||
return msl(CharT{'E'});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Period>
|
|
||||||
constexpr
|
|
||||||
auto
|
|
||||||
get_units(Period p)
|
|
||||||
{
|
|
||||||
return msl<CharT>(p) + string_literal<CharT, 2>{"s"};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
auto
|
|
||||||
get_units(std::ratio<1>)
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 2>{"s"};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
auto
|
|
||||||
get_units(std::ratio<60>)
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 4>{"min"};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
auto
|
|
||||||
get_units(std::ratio<3600>)
|
|
||||||
{
|
|
||||||
return string_literal<CharT, 2>{"h"};
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // __cplusplus < 201402
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::string
|
|
||||||
to_string(std::uint64_t x)
|
|
||||||
{
|
|
||||||
return std::to_string(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
std::basic_string<CharT>
|
|
||||||
to_string(std::uint64_t x)
|
|
||||||
{
|
|
||||||
auto y = std::to_string(x);
|
|
||||||
return std::basic_string<CharT>(y.begin(), y.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, std::intmax_t N, std::intmax_t D>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::ratio<N, D>::type::den != 1,
|
|
||||||
std::basic_string<CharT>
|
|
||||||
>::type
|
|
||||||
msl(std::ratio<N, D>) noexcept
|
|
||||||
{
|
|
||||||
using R = typename std::ratio<N, D>::type;
|
|
||||||
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} +
|
|
||||||
to_string<CharT>(R::den) + CharT{']'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, std::intmax_t N, std::intmax_t D>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::ratio<N, D>::type::den == 1,
|
|
||||||
std::basic_string<CharT>
|
|
||||||
>::type
|
|
||||||
msl(std::ratio<N, D>) noexcept
|
|
||||||
{
|
|
||||||
using R = typename std::ratio<N, D>::type;
|
|
||||||
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::atto) noexcept
|
|
||||||
{
|
|
||||||
return {'a'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::femto) noexcept
|
|
||||||
{
|
|
||||||
return {'f'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::pico) noexcept
|
|
||||||
{
|
|
||||||
return {'p'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::nano) noexcept
|
|
||||||
{
|
|
||||||
return {'n'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::is_same<CharT, char>::value,
|
|
||||||
std::string
|
|
||||||
>::type
|
|
||||||
msl(std::micro) noexcept
|
|
||||||
{
|
|
||||||
return "\xC2\xB5";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
!std::is_same<CharT, char>::value,
|
|
||||||
std::basic_string<CharT>
|
|
||||||
>::type
|
|
||||||
msl(std::micro) noexcept
|
|
||||||
{
|
|
||||||
return {CharT(static_cast<unsigned char>('\xB5'))};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::milli) noexcept
|
|
||||||
{
|
|
||||||
return {'m'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::centi) noexcept
|
|
||||||
{
|
|
||||||
return {'c'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::deci) noexcept
|
|
||||||
{
|
|
||||||
return {'d'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::deca) noexcept
|
|
||||||
{
|
|
||||||
return {'d', 'a'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::hecto) noexcept
|
|
||||||
{
|
|
||||||
return {'h'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::kilo) noexcept
|
|
||||||
{
|
|
||||||
return {'k'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::mega) noexcept
|
|
||||||
{
|
|
||||||
return {'M'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::giga) noexcept
|
|
||||||
{
|
|
||||||
return {'G'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::tera) noexcept
|
|
||||||
{
|
|
||||||
return {'T'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::peta) noexcept
|
|
||||||
{
|
|
||||||
return {'P'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
constexpr
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
msl(std::exa) noexcept
|
|
||||||
{
|
|
||||||
return {'E'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Period>
|
|
||||||
std::basic_string<CharT>
|
|
||||||
get_units(Period p)
|
|
||||||
{
|
|
||||||
return msl<CharT>(p) + CharT{'s'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
std::basic_string<CharT>
|
|
||||||
get_units(std::ratio<1>)
|
|
||||||
{
|
|
||||||
return {'s'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
std::basic_string<CharT>
|
|
||||||
get_units(std::ratio<60>)
|
|
||||||
{
|
|
||||||
return {'m', 'i', 'n'};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT>
|
|
||||||
std::basic_string<CharT>
|
|
||||||
get_units(std::ratio<3600>)
|
|
||||||
{
|
|
||||||
return {'h'};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __cplusplus >= 201402
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Rep, class Period>
|
|
||||||
inline
|
|
||||||
std::basic_ostream<CharT, Traits>&
|
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os,
|
|
||||||
const std::chrono::duration<Rep, Period>& d)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return os << to_string(d.count()) + detail::get_units<CharT>(typename Period::type{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace date
|
|
||||||
|
|
||||||
#endif // CHRONO_IO_H
|
#endif // CHRONO_IO_H
|
||||||
|
672
date.h
672
date.h
@ -35,6 +35,7 @@
|
|||||||
#if !(__cplusplus >= 201402)
|
#if !(__cplusplus >= 201402)
|
||||||
# include <cmath>
|
# include <cmath>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
@ -6654,6 +6655,677 @@ parse(const CharT* format, Parsable& tp,
|
|||||||
return {format, tp, &abbrev, &offset};
|
return {format, tp, &abbrev, &offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// duration streaming
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if __cplusplus >= 201402
|
||||||
|
|
||||||
|
template <class CharT, std::size_t N>
|
||||||
|
class string_literal
|
||||||
|
{
|
||||||
|
CharT p_[N];
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_iterator = const CharT*;
|
||||||
|
|
||||||
|
string_literal(string_literal const&) = default;
|
||||||
|
string_literal& operator=(string_literal const&) = delete;
|
||||||
|
|
||||||
|
template <std::size_t N1 = 2,
|
||||||
|
class = std::enable_if_t<N1 == N>>
|
||||||
|
CONSTCD14 string_literal(CharT c) NOEXCEPT
|
||||||
|
: p_{c}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT
|
||||||
|
: p_{}
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
p_[i] = a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U = CharT, class = std::enable_if_t<1 < sizeof(U)>>
|
||||||
|
CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT
|
||||||
|
: p_{}
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
p_[i] = a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT2, class = std::enable_if_t<!std::is_same<CharT2, CharT>{}>>
|
||||||
|
CONSTCD14 string_literal(string_literal<CharT2, N> const& a) NOEXCEPT
|
||||||
|
: p_{}
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
p_[i] = a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N1, std::size_t N2,
|
||||||
|
class = std::enable_if_t<N1 + N2 - 1 == N>>
|
||||||
|
CONSTCD14 string_literal(const string_literal<CharT, N1>& x,
|
||||||
|
const string_literal<CharT, N2>& y) NOEXCEPT
|
||||||
|
: p_{}
|
||||||
|
{
|
||||||
|
std::size_t i = 0;
|
||||||
|
for (; i < N1-1; ++i)
|
||||||
|
p_[i] = x[i];
|
||||||
|
for (std::size_t j = 0; j < N2; ++j, ++i)
|
||||||
|
p_[i] = y[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSTCD14 const CharT* data() const NOEXCEPT {return p_;}
|
||||||
|
CONSTCD14 std::size_t size() const NOEXCEPT {return N-1;}
|
||||||
|
|
||||||
|
CONSTCD14 const_iterator begin() const NOEXCEPT {return p_;}
|
||||||
|
CONSTCD14 const_iterator end() const NOEXCEPT {return p_ + N-1;}
|
||||||
|
|
||||||
|
CONSTCD14 CharT const& operator[](std::size_t n) const NOEXCEPT
|
||||||
|
{
|
||||||
|
return p_[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Traits>
|
||||||
|
friend
|
||||||
|
std::basic_ostream<CharT, Traits>&
|
||||||
|
operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s)
|
||||||
|
{
|
||||||
|
return os << s.p_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
string_literal<std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>,
|
||||||
|
N1 + N2 - 1>
|
||||||
|
operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT
|
||||||
|
{
|
||||||
|
using CharT = std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>;
|
||||||
|
return string_literal<CharT, N1 + N2 - 1>{string_literal<CharT, N1>{x},
|
||||||
|
string_literal<CharT, N2>{y}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Alloc, std::size_t N>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT, Traits, Alloc>
|
||||||
|
operator+(std::basic_string<CharT, Traits, Alloc> x,
|
||||||
|
const string_literal<CharT, N>& y) NOEXCEPT
|
||||||
|
{
|
||||||
|
x.append(y.data(), y.size());
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, std::size_t N>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
string_literal<CharT, N>
|
||||||
|
msl(const CharT(&a)[N]) NOEXCEPT
|
||||||
|
{
|
||||||
|
return string_literal<CharT, N>{a};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT,
|
||||||
|
class = std::enable_if_t<std::is_same<CharT, char>{} ||
|
||||||
|
std::is_same<CharT, wchar_t>{} ||
|
||||||
|
std::is_same<CharT, char16_t>{} ||
|
||||||
|
std::is_same<CharT, char32_t>{}>>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
string_literal<CharT, 2>
|
||||||
|
msl(CharT c) NOEXCEPT
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 2>{c};
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSTCD14
|
||||||
|
std::size_t
|
||||||
|
to_string_len(std::intmax_t i)
|
||||||
|
{
|
||||||
|
std::size_t r = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i /= 10;
|
||||||
|
++r;
|
||||||
|
} while (i > 0);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::intmax_t N>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
N < 10,
|
||||||
|
string_literal<char, to_string_len(N)+1>
|
||||||
|
>
|
||||||
|
msl() NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(char(N % 10 + '0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::intmax_t N>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
10 <= N,
|
||||||
|
string_literal<char, to_string_len(N)+1>
|
||||||
|
>
|
||||||
|
msl() NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl<N/10>() + msl(char(N % 10 + '0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, std::intmax_t N, std::intmax_t D>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
std::ratio<N, D>::type::den != 1,
|
||||||
|
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) +
|
||||||
|
to_string_len(std::ratio<N, D>::type::den) + 4>
|
||||||
|
>
|
||||||
|
msl(std::ratio<N, D>) NOEXCEPT
|
||||||
|
{
|
||||||
|
using R = typename std::ratio<N, D>::type;
|
||||||
|
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) +
|
||||||
|
msl<R::den>() + msl(CharT{']'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, std::intmax_t N, std::intmax_t D>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
std::ratio<N, D>::type::den == 1,
|
||||||
|
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3>
|
||||||
|
>
|
||||||
|
msl(std::ratio<N, D>) NOEXCEPT
|
||||||
|
{
|
||||||
|
using R = typename std::ratio<N, D>::type;
|
||||||
|
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::atto) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'a'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::femto) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'f'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::pico) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'p'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::nano) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'n'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
std::is_same<CharT, char>{},
|
||||||
|
string_literal<char, 3>
|
||||||
|
>
|
||||||
|
msl(std::micro) NOEXCEPT
|
||||||
|
{
|
||||||
|
return string_literal<char, 3>{"\xC2\xB5"};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
std::enable_if_t
|
||||||
|
<
|
||||||
|
!std::is_same<CharT, char>{},
|
||||||
|
string_literal<CharT, 2>
|
||||||
|
>
|
||||||
|
msl(std::micro) NOEXCEPT
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::milli) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'m'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::centi) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'c'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::deci) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'d'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::deca) NOEXCEPT
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 3>{"da"};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::hecto) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'h'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::kilo) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'k'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::mega) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'M'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::giga) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'G'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::tera) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'T'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::peta) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'P'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
auto
|
||||||
|
msl(std::exa) NOEXCEPT
|
||||||
|
{
|
||||||
|
return msl(CharT{'E'});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Period>
|
||||||
|
CONSTCD14
|
||||||
|
auto
|
||||||
|
get_units(Period p)
|
||||||
|
{
|
||||||
|
return msl<CharT>(p) + string_literal<CharT, 2>{"s"};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
auto
|
||||||
|
get_units(std::ratio<1>)
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 2>{"s"};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
auto
|
||||||
|
get_units(std::ratio<60>)
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 4>{"min"};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
CONSTCD14
|
||||||
|
auto
|
||||||
|
get_units(std::ratio<3600>)
|
||||||
|
{
|
||||||
|
return string_literal<CharT, 2>{"h"};
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __cplusplus < 201402
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::string
|
||||||
|
to_string(std::uint64_t x)
|
||||||
|
{
|
||||||
|
return std::to_string(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
std::basic_string<CharT>
|
||||||
|
to_string(std::uint64_t x)
|
||||||
|
{
|
||||||
|
auto y = std::to_string(x);
|
||||||
|
return std::basic_string<CharT>(y.begin(), y.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, std::intmax_t N, std::intmax_t D>
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::ratio<N, D>::type::den != 1,
|
||||||
|
std::basic_string<CharT>
|
||||||
|
>::type
|
||||||
|
msl(std::ratio<N, D>)
|
||||||
|
{
|
||||||
|
using R = typename std::ratio<N, D>::type;
|
||||||
|
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} +
|
||||||
|
to_string<CharT>(R::den) + CharT{']'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, std::intmax_t N, std::intmax_t D>
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::ratio<N, D>::type::den == 1,
|
||||||
|
std::basic_string<CharT>
|
||||||
|
>::type
|
||||||
|
msl(std::ratio<N, D>)
|
||||||
|
{
|
||||||
|
using R = typename std::ratio<N, D>::type;
|
||||||
|
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::atto)
|
||||||
|
{
|
||||||
|
return {'a'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::femto)
|
||||||
|
{
|
||||||
|
return {'f'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::pico)
|
||||||
|
{
|
||||||
|
return {'p'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::nano)
|
||||||
|
{
|
||||||
|
return {'n'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::is_same<CharT, char>::value,
|
||||||
|
std::string
|
||||||
|
>::type
|
||||||
|
msl(std::micro)
|
||||||
|
{
|
||||||
|
return "\xC2\xB5";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!std::is_same<CharT, char>::value,
|
||||||
|
std::basic_string<CharT>
|
||||||
|
>::type
|
||||||
|
msl(std::micro)
|
||||||
|
{
|
||||||
|
return {CharT(static_cast<unsigned char>('\xB5'))};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::milli)
|
||||||
|
{
|
||||||
|
return {'m'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::centi)
|
||||||
|
{
|
||||||
|
return {'c'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::deci)
|
||||||
|
{
|
||||||
|
return {'d'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::deca)
|
||||||
|
{
|
||||||
|
return {'d', 'a'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::hecto)
|
||||||
|
{
|
||||||
|
return {'h'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::kilo)
|
||||||
|
{
|
||||||
|
return {'k'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::mega)
|
||||||
|
{
|
||||||
|
return {'M'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::giga)
|
||||||
|
{
|
||||||
|
return {'G'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::tera)
|
||||||
|
{
|
||||||
|
return {'T'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::peta)
|
||||||
|
{
|
||||||
|
return {'P'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
msl(std::exa)
|
||||||
|
{
|
||||||
|
return {'E'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Period>
|
||||||
|
std::basic_string<CharT>
|
||||||
|
get_units(Period p)
|
||||||
|
{
|
||||||
|
return msl<CharT>(p) + CharT{'s'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
std::basic_string<CharT>
|
||||||
|
get_units(std::ratio<1>)
|
||||||
|
{
|
||||||
|
return {'s'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
std::basic_string<CharT>
|
||||||
|
get_units(std::ratio<60>)
|
||||||
|
{
|
||||||
|
return {'m', 'i', 'n'};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
std::basic_string<CharT>
|
||||||
|
get_units(std::ratio<3600>)
|
||||||
|
{
|
||||||
|
return {'h'};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus >= 201402
|
||||||
|
|
||||||
|
template <class CharT, class Traits = std::char_traits<CharT>>
|
||||||
|
struct make_string;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct make_string<char>
|
||||||
|
{
|
||||||
|
template <class Rep>
|
||||||
|
static
|
||||||
|
std::string
|
||||||
|
from(Rep n)
|
||||||
|
{
|
||||||
|
return std::to_string(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Traits>
|
||||||
|
struct make_string<char, Traits>
|
||||||
|
{
|
||||||
|
template <class Rep>
|
||||||
|
static
|
||||||
|
std::basic_string<char, Traits>
|
||||||
|
from(Rep n)
|
||||||
|
{
|
||||||
|
auto s = std::to_string(n);
|
||||||
|
return std::basic_string<char, Traits>(s.begin(), s.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct make_string<wchar_t>
|
||||||
|
{
|
||||||
|
template <class Rep>
|
||||||
|
static
|
||||||
|
std::wstring
|
||||||
|
from(Rep n)
|
||||||
|
{
|
||||||
|
return std::to_wstring(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Traits>
|
||||||
|
struct make_string<wchar_t, Traits>
|
||||||
|
{
|
||||||
|
template <class Rep>
|
||||||
|
static
|
||||||
|
std::wstring
|
||||||
|
from(Rep n)
|
||||||
|
{
|
||||||
|
auto s = std::to_wstring(n);
|
||||||
|
return std::basic_string<wchar_t, Traits>(s.begin(), s.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Rep, class Period>
|
||||||
|
inline
|
||||||
|
std::basic_ostream<CharT, Traits>&
|
||||||
|
operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||||
|
const std::chrono::duration<Rep, Period>& d)
|
||||||
|
{
|
||||||
|
using namespace detail;
|
||||||
|
return os << make_string<CharT, Traits>::from(d.count()) +
|
||||||
|
get_units<CharT>(typename Period::type{});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace date
|
} // namespace date
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user