mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 00:14:07 +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
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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).
|
||||
// We did not mean to shout.
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
// This functionality has moved to "date.h"
|
||||
|
||||
namespace date
|
||||
{
|
||||
|
||||
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
|
||||
#include "date.h"
|
||||
|
||||
#endif // CHRONO_IO_H
|
||||
|
672
date.h
672
date.h
@ -35,6 +35,7 @@
|
||||
#if !(__cplusplus >= 201402)
|
||||
# include <cmath>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
@ -6654,6 +6655,677 @@ parse(const CharT* format, Parsable& tp,
|
||||
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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user