chromium/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h

// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   https://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_

#include <cstdint>
#include <limits>
#include <ostream>
#include <type_traits>

#include "absl/base/config.h"

// Disable constexpr support unless we are in C++14 mode.
#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
#define CONSTEXPR_D
#define CONSTEXPR_F
#define CONSTEXPR_M
#else
#define CONSTEXPR_D
#define CONSTEXPR_F
#define CONSTEXPR_M
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace time_internal {
namespace cctz {

// Support years that at least span the range of 64-bit time_t values.
year_t;

// Type alias that indicates an argument is not normalized (e.g., the
// constructor parameters and operands/results of addition/subtraction).
diff_t;

namespace detail {

// Type aliases that indicate normalized argument values.
month_t;   // [1:12]
day_t;     // [1:31]
hour_t;    // [0:23]
minute_t;  // [0:59]
second_t;  // [0:59]

// Normalized civil-time fields: Y-M-D HH:MM:SS.
struct fields {};

struct second_tag {};
struct minute_tag : second_tag {};
struct hour_tag : minute_tag {};
struct day_tag : hour_tag {};
struct month_tag : day_tag {};
struct year_tag : month_tag {};

////////////////////////////////////////////////////////////////////////

// Field normalization (without avoidable overflow).

namespace impl {

CONSTEXPR_F bool is_leap_year(year_t y) noexcept {}
CONSTEXPR_F int year_index(year_t y, month_t m) noexcept {}
CONSTEXPR_F int days_per_century(int yi) noexcept {}
CONSTEXPR_F int days_per_4years(int yi) noexcept {}
CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept {}
CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {}

CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh,
                         minute_t mm, second_t ss) noexcept {}
CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh,
                         minute_t mm, second_t ss) noexcept {}
CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh,
                          minute_t mm, second_t ss) noexcept {}
CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
                         diff_t mm, second_t ss) noexcept {}
CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
                         diff_t ss) noexcept {}

}  // namespace impl

////////////////////////////////////////////////////////////////////////

// Increments the indicated (normalized) field by "n".
CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept {}
CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept {}
CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept {}
CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept {}
CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept {}
CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept {}

////////////////////////////////////////////////////////////////////////

namespace impl {

// Returns (v * f + a) but avoiding intermediate overflow when possible.
CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept {}

// Map a (normalized) Y/M/D to the number of days before/after 1970-01-01.
// Probably overflows for years outside [-292277022656:292277026595].
CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept {}

// Returns the difference in days between two normalized Y-M-D tuples.
// ymd_ord() will encounter integer overflow given extreme year values,
// yet the difference between two such extreme values may actually be
// small, so we take a little care to avoid overflow when possible by
// exploiting the 146097-day cycle.
CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2,
                                  month_t m2, day_t d2) noexcept {}

}  // namespace impl

// Returns the difference between fields structs using the indicated unit.
CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept {}
CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept {}
CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept {}
CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept {}
CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept {}
CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept {}

////////////////////////////////////////////////////////////////////////

// Aligns the (normalized) fields struct to the indicated field.
CONSTEXPR_F fields align(second_tag, fields f) noexcept {}
CONSTEXPR_F fields align(minute_tag, fields f) noexcept {}
CONSTEXPR_F fields align(hour_tag, fields f) noexcept {}
CONSTEXPR_F fields align(day_tag, fields f) noexcept {}
CONSTEXPR_F fields align(month_tag, fields f) noexcept {}
CONSTEXPR_F fields align(year_tag, fields f) noexcept {}

////////////////////////////////////////////////////////////////////////

namespace impl {

template <typename H>
H AbslHashValueImpl(second_tag, H h, fields f) {}
template <typename H>
H AbslHashValueImpl(minute_tag, H h, fields f) {}
template <typename H>
H AbslHashValueImpl(hour_tag, H h, fields f) {}
template <typename H>
H AbslHashValueImpl(day_tag, H h, fields f) {}
template <typename H>
H AbslHashValueImpl(month_tag, H h, fields f) {}
template <typename H>
H AbslHashValueImpl(year_tag, H h, fields f) {}

}  // namespace impl

////////////////////////////////////////////////////////////////////////

template <typename T>
class civil_time {};

// Disallows difference between differently aligned types.
// auto n = civil_day(...) - civil_hour(...);  // would be confusing.
template <typename T, typename U>
CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete;

civil_year;
civil_month;
civil_day;
civil_hour;
civil_minute;
civil_second;

////////////////////////////////////////////////////////////////////////

// Relational operators that work with differently aligned objects.
// Always compares all six fields.
template <typename T1, typename T2>
CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
                           const civil_time<T2>& rhs) noexcept {}
template <typename T1, typename T2>
CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {}
template <typename T1, typename T2>
CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {}
template <typename T1, typename T2>
CONSTEXPR_F bool operator>(const civil_time<T1>& lhs,
                           const civil_time<T2>& rhs) noexcept {}
template <typename T1, typename T2>
CONSTEXPR_F bool operator==(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {}
template <typename T1, typename T2>
CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {}

////////////////////////////////////////////////////////////////////////

enum class weekday {};

CONSTEXPR_F weekday get_weekday(const civil_second& cs) noexcept {}

////////////////////////////////////////////////////////////////////////

CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {}

CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {}

CONSTEXPR_F int get_yearday(const civil_second& cs) noexcept {}

////////////////////////////////////////////////////////////////////////

std::ostream& operator<<(std::ostream& os, const civil_year& y);
std::ostream& operator<<(std::ostream& os, const civil_month& m);
std::ostream& operator<<(std::ostream& os, const civil_day& d);
std::ostream& operator<<(std::ostream& os, const civil_hour& h);
std::ostream& operator<<(std::ostream& os, const civil_minute& m);
std::ostream& operator<<(std::ostream& os, const civil_second& s);
std::ostream& operator<<(std::ostream& os, weekday wd);

}  // namespace detail
}  // namespace cctz
}  // namespace time_internal
ABSL_NAMESPACE_END
}  // namespace absl

#undef CONSTEXPR_M
#undef CONSTEXPR_F
#undef CONSTEXPR_D

#endif  // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_