inline
  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_duration& td)
  {
    // need to create a std::string and parse it
    std::basic_string<charT> inp_s;
    std::stringstream out_ss;
    is >> inp_s;
    typename std::basic_string<charT>::iterator b = inp_s.begin();
    // need to use both iterators because there is no requirement
    // for the data held by a std::basic_string<> be terminated with
    // any marker (such as '\0').
    typename std::basic_string<charT>::iterator e = inp_s.end();
    while(b != e){
      out_ss << is.narrow(*b, 0);
      ++b;
    }

    td = date_time::parse_delimited_time_duration<time_duration>(out_ss.str());
    return is;
  }
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, pcg128_t& value)
{
    typename std::basic_istream<CharT,Traits>::sentry s(in);

    if (!s)
         return in;

    constexpr auto BASE = pcg128_t(10ULL);
    pcg128_t current(0ULL);
    bool did_nothing = true;
    bool overflow = false;
    for(;;) {
        CharT wide_ch = in.get();
        if (!in.good())
            break;
        auto ch = in.narrow(wide_ch, '\0');
        if (ch < '0' || ch > '9') {
            in.unget();
            break;
        }
        did_nothing = false;
        pcg128_t digit(uint32_t(ch - '0'));
        pcg128_t timesbase = current*BASE;
        overflow = overflow || timesbase < current;
        current = timesbase + digit;
        overflow = overflow || current < digit;
    }

    if (did_nothing || overflow) {
        in.setstate(std::ios::failbit);
        if (overflow)
            current = ~pcg128_t(0ULL);
    }

    value = current;

    return in;
}