예제 #1
0
_LIBCPP_CONSTEXPR_AFTER_CXX11
bool is_representable(file_time_type const& tm) {
  auto secs = duration_cast<seconds>(tm.time_since_epoch());
  auto nsecs = duration_cast<nanoseconds>(tm.time_since_epoch() - secs);
  if (nsecs.count() < 0) {
    secs = secs +  seconds(1);
    nsecs = nsecs + seconds(1);
  }
  using TLim = numeric_limits<time_t>;
  if (secs.count() >= 0)
    return secs.count() <= TLim::max();
  return secs.count() >= TLim::min();
}
예제 #2
0
static bool CompareTime(file_time_type t1, file_time_type t2) {
  auto min_secs = duration_cast<Sec>(file_time_type::min().time_since_epoch());
  bool IsMin =
      t1.time_since_epoch() < min_secs || t2.time_since_epoch() < min_secs;

  if (SupportsNanosecondRoundTrip && (!IsMin || SupportsMinRoundTrip))
    return t1 == t2;
  if (IsMin) {
    return duration_cast<Sec>(t1.time_since_epoch()) ==
           duration_cast<Sec>(t2.time_since_epoch());
  }
  file_time_type::duration dur;
  if (t1 > t2)
    dur = t1 - t2;
  else
    dur = t2 - t1;
  if (WorkaroundStatTruncatesToSeconds)
    return duration_cast<Sec>(dur).count() == 0;
  return duration_cast<MicroSec>(dur).count() == 0;
}
예제 #3
0
// Check if a time point is representable on a given filesystem. Check that:
// (A) 'tp' is representable as a time_t
// (B) 'tp' is non-negative or the filesystem supports negative times.
// (C) 'tp' is not 'file_time_type::max()' or the filesystem supports the max
//     value.
// (D) 'tp' is not 'file_time_type::min()' or the filesystem supports the min
//     value.
inline bool TimeIsRepresentableByFilesystem(file_time_type tp) {
  TimeSpec ts = {};
  if (!ConvertToTimeSpec(ts, tp))
    return false;
  else if (tp.time_since_epoch().count() < 0 && !SupportsNegativeTimes)
    return false;
  else if (tp == file_time_type::max() && !SupportsMaxTime)
    return false;
  else if (tp == file_time_type::min() && !SupportsMinTime)
    return false;
  return true;
}
예제 #4
0
bool ConvertToTimeSpec(TimeSpec& ts, file_time_type ft) {
  using SecFieldT = decltype(TimeSpec::tv_sec);
  using NSecFieldT = decltype(TimeSpec::tv_nsec);
  using SecLim = std::numeric_limits<SecFieldT>;
  using NSecLim = std::numeric_limits<NSecFieldT>;

  auto secs = duration_cast<Sec>(ft.time_since_epoch());
  auto nsecs = duration_cast<NanoSec>(ft.time_since_epoch() - secs);
  if (nsecs.count() < 0) {
    if (Sec::min().count() > SecLim::min()) {
      secs += Sec(1);
      nsecs -= Sec(1);
    } else {
      nsecs = NanoSec(0);
    }
  }
  if (SecLim::max() < secs.count() || SecLim::min() > secs.count())
    return false;
  if (NSecLim::max() < nsecs.count() || NSecLim::min() > nsecs.count())
    return false;
  ts.tv_sec = secs.count();
  ts.tv_nsec = nsecs.count();
  return true;
}
예제 #5
0
bool set_times_checked(time_t* sec_out, SubSecT* subsec_out, file_time_type tp) {
    using namespace chrono;
    auto dur = tp.time_since_epoch();
    auto sec_dur = duration_cast<seconds>(dur);
    auto subsec_dur = duration_cast<SubSecDurT>(dur - sec_dur);
    // The tv_nsec and tv_usec fields must not be negative so adjust accordingly
    if (subsec_dur.count() < 0) {
        if (sec_dur.count() > min_seconds) {
            sec_dur -= seconds(1);
            subsec_dur += seconds(1);
        } else {
            subsec_dur = SubSecDurT::zero();
        }
    }
    return checked_set(sec_out, sec_dur.count())
        && checked_set(subsec_out, subsec_dur.count());
}
예제 #6
0
inline bool TimeIsRepresentableAsTimeT(file_time_type tp) {
    using namespace std::chrono;
    using Lim = std::numeric_limits<std::time_t>;
    auto sec = duration_cast<seconds>(tp.time_since_epoch()).count();
    return (sec >= Lim::min() && sec <= Lim::max());
}