mirror of
https://github.com/HowardHinnant/date.git
synced 2025-08-04 05:04:27 +02:00
Updated FAQ (markdown)
59
FAQ.md
59
FAQ.md
@@ -1,3 +1,58 @@
|
|||||||
# Frequently Asked Questions
|
##Contents
|
||||||
|
- [Why can't I do day arithmetic on a `year_month_day`?](#day_arithmetic)
|
||||||
|
|
||||||
Why can't I do day arithmetic on a `year_month_day`?
|
***
|
||||||
|
|
||||||
|
<a name="day_arithmetic"></a>
|
||||||
|
### Why can't I do day arithmetic on a `year_month_day`?
|
||||||
|
|
||||||
|
This library is meant to be a foundational library upon which you can efficiently build higher-level date libraries (like tz.h). A core component of this library is that it makes expensive computations explicit, so that you can see where they are in your code. Higher-level code can hide these expensive/explicit operations as desired.
|
||||||
|
|
||||||
|
A good way to estimate the cost of any given date computation is to count the number of conversions from a field type (e.g. `year_month_day` or `year_month_weekday`) to a serial type (e.g. `day_point`), and vice-versa. As an example, here is a real-world example (found in the issues list):
|
||||||
|
|
||||||
|
We need to compute the day after the 3rd Tuesday of the month. If day-oriented arithmetic was allowed on `year_month_weekday`, that would be in the form of a function like this:
|
||||||
|
|
||||||
|
constexpr
|
||||||
|
year_month_weekday
|
||||||
|
operator+(const year_month_weekday& ymwd, const days& dd) noexcept
|
||||||
|
{
|
||||||
|
return year_month_weekday{day_point{ymwd} + dd};
|
||||||
|
}
|
||||||
|
|
||||||
|
The programmer would probably use it like this:
|
||||||
|
|
||||||
|
year_month_day
|
||||||
|
get_meeting_date(year y, month m)
|
||||||
|
{
|
||||||
|
return year_month_day{tue[3]/m/y + days{1}};
|
||||||
|
}
|
||||||
|
|
||||||
|
That is super-compact syntax! Here is what it costs:
|
||||||
|
|
||||||
|
1. Convert `tue[3]/m/y` (`year_month_weekday`) to `day_point` in order to add `days`.
|
||||||
|
2. Convert the `day_point` computed back to `year_month_weekday`.
|
||||||
|
3. Convert the temporary `year_month_weekday` computed in 2 back to `day_point`.
|
||||||
|
4. Convert the `day_point` to a `year_month_day`.
|
||||||
|
|
||||||
|
4 conversions.
|
||||||
|
|
||||||
|
Here is the way you have to write this function today (because `tue[3]/m/y + days{1}` is a compile-time error):
|
||||||
|
|
||||||
|
year_month_day
|
||||||
|
get_meeting_date(year y, month m)
|
||||||
|
{
|
||||||
|
return year_month_day{day_point{tue[3]/m/y} + days{1}};
|
||||||
|
}
|
||||||
|
|
||||||
|
The syntax is slightly more verbose in that you have to explicitly convert the `year_month_weekday` into a `day_point` in order to perform the day-oriented arithmetic. Here is what it costs:
|
||||||
|
|
||||||
|
1. Convert `tue[3]/m/y` (`year_month_weekday`) to `day_point` in order to add `days`.
|
||||||
|
2. Convert the `day_point` to a `year_month_day`.
|
||||||
|
|
||||||
|
2 conversions. Roughly twice as fast!
|
||||||
|
|
||||||
|
This philosophy is similar to that which we have for containers: It would be super easy to create `vector<T>::push_front(const T&)`. But that would make it too easy for programmers to write inefficient code. The compiler helps remind the programmer that perhaps `deque<T>` or `list<T>` would be a better choice when he attempts to code with `vector<T>::push_front(const T&)`.
|
||||||
|
|
||||||
|
It would be very easy to add `T& list<T>::operator[](size_t index)`. But that would encourage the programmer to use `list<T>` when a random-access container would probably be more appropriate for the task.
|
||||||
|
|
||||||
|
This library continues in that tradition: The expensive operations are not hidden.
|
Reference in New Issue
Block a user