BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_packedcalendar.h
Go to the documentation of this file.
1/// @file bdlt_packedcalendar.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_packedcalendar.h -*-C++-*-
8#ifndef INCLUDED_BDLT_PACKEDCALENDAR
9#define INCLUDED_BDLT_PACKEDCALENDAR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_packedcalendar bdlt_packedcalendar
15/// @brief Provide a compact repository for weekend/holiday information.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_packedcalendar
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_packedcalendar-purpose"> Purpose</a>
25/// * <a href="#bdlt_packedcalendar-classes"> Classes </a>
26/// * <a href="#bdlt_packedcalendar-description"> Description </a>
27/// * <a href="#bdlt_packedcalendar-weekend-days-and-weekend-days-transitions"> Weekend Days and Weekend-Days Transitions </a>
28/// * <a href="#bdlt_packedcalendar-nested-iterators"> Nested Iterators </a>
29/// * <a href="#bdlt_packedcalendar-iterator-invalidation"> Iterator Invalidation </a>
30/// * <a href="#bdlt_packedcalendar-performance-and-exception-safety-guarantees"> Performance and Exception-Safety Guarantees </a>
31/// * <a href="#bdlt_packedcalendar-usage"> Usage </a>
32/// * <a href="#bdlt_packedcalendar-example-1-populating-packed-calendars"> Example 1: Populating Packed Calendars </a>
33/// * <a href="#bdlt_packedcalendar-example-2-using-packed-calendars"> Example 2: Using Packed Calendars </a>
34///
35/// # Purpose {#bdlt_packedcalendar-purpose}
36/// Provide a compact repository for weekend/holiday information.
37///
38/// # Classes {#bdlt_packedcalendar-classes}
39///
40/// - bdlt::PackedCalendar: compact repository of weekend/holiday information
41///
42/// @see bdlt_calendar
43///
44/// # Description {#bdlt_packedcalendar-description}
45/// This component provides a value-semantic class,
46/// `bdlt::PackedCalendar`, that represents weekend and holiday information over
47/// a *valid* *range* of dates. A `bdlt::PackedCalendar` is an approximation to
48/// the same *mathematical* type, and is capable of representing the same subset
49/// of *mathematical* values, as a `bdlt::Calendar`.
50///
51/// But unlike `bdlt::Calendar`, which is optimized for runtime efficiency,
52/// `bdlt::PackedCalendar` is designed to minimize the amount of in-process
53/// memory required to represent that information. For example, a packed
54/// calendar storing 250 holidays and holiday codes can consume as little as
55/// approximately 0.75K bytes (e.g., 2 bytes per holiday plus 1 byte per
56/// holiday code) to as much as approximately 3K bytes (e.g., 8 bytes per
57/// holiday plus 4 bytes per holiday code) depending upon the data of the
58/// calendar. For typical calendars having a range of 40 years and 10 holidays
59/// per year, the expected size of the packed calendar is about half that of a
60/// similar implementation using a non-packed structure.
61///
62/// Default-constructed calendars are empty, and have an empty valid range.
63/// Calendars can also be constructed with an initial (non-empty) valid range,
64/// implying that all dates within that range are business days. The
65/// `setValidRange` and `addDay` methods modify the valid range of a calendar,
66/// and a suite of "add" methods can be used to populate a calendar with
67/// weekend days and holidays.
68///
69/// The `addHolidayCode` method associates an integer "holiday code" with a
70/// specific date, and can be called repeatedly with different integers and the
71/// same date to build up a set of holiday codes for that date. Note that
72/// holiday codes are unique integers that, from the perspective of the
73/// calendar, have no particular meaning. Typically, the user will choose
74/// holiday code values that are indices into an auxiliary collection (such as a
75/// `bsl::vector<bsl::string>`) to identify holiday names for end-user display.
76///
77/// Once a calendar is populated, a rich set of accessor methods can be used to
78/// determine, e.g., if a given date is a business day, or the number of
79/// non-business days within some subrange of the calendar. The holidays
80/// within a calendar can be obtained in increasing (chronological) order using
81/// an iterator identified by the nested `HolidayConstIterator` `typedef`. The
82/// set of holiday codes associated with an arbitrary date in a
83/// `bdlt::PackedCalendar` (or the current holiday referred to by a
84/// `HolidayConstIterator`) can be obtained in increasing (numerical) order
85/// using an iterator identified by the nested `HolidayCodeConstIterator`
86/// `typedef` (see below).
87///
88/// Calendars are value-semantic objects, and, as such, necessarily support all
89/// of the standard value-semantic operations, such as default construction,
90/// copy construction and copy assignment, equality comparison, and
91/// externalization (BDEX streaming, in particular). Calendars also support
92/// the notions of both union and intersection merging operations, whereby a
93/// calendar can change its value to contain the union or intersection of its
94/// own contained weekend days, holidays, and holiday codes with those of
95/// another calendar object. Such merging operations will, in general, also
96/// alter the valid range of the resulting calendar. Note that merged
97/// calendars can be significantly more efficient for certain repeated
98/// "is-common-business-day" determinations among two or more calendars.
99///
100/// ## Weekend Days and Weekend-Days Transitions {#bdlt_packedcalendar-weekend-days-and-weekend-days-transitions}
101///
102///
103/// A calendar maintains a set of dates considered to be weekend days.
104/// Typically, a calendar's weekend days fall on the same days of the week for
105/// the entire range of a calendar. For example, the weekend for United States
106/// has consisted of Saturday and Sunday since the year 1940. The
107/// `addWeekendDay` and `addWeekendDays` methods can be used to specify the
108/// weekend days for these calendars.
109///
110/// However, sometimes a calendar's weekend days changes over time. For
111/// example, Bangladesh's weekend consisted of Friday until June 1, 1997 when
112/// Bangladesh changed its weekends to contain both Friday and Saturday. Later,
113/// on October 1, 2001, Bangladesh reverted to a weekend of only Friday, until
114/// on September 9, 2009, Bangladesh again changed its weekends to include both
115/// Friday and Saturday.
116///
117/// To optimize for space allocation while supporting both consistent and
118/// changing weekend days, a calendar represents weekend information using a
119/// sequence of "weekend-days transitions", each of which comprises a date and a
120/// set of days of the week considered to be the weekend on and after that
121/// date. To represent the weekend days of Bangladesh, a calendar can use a
122/// sequence of four weekend-days transitions: (1) a transition on January 1,
123/// 0001 having a weekend day set containing only Friday, (2) a transition at
124/// June 1, 1997 having a weekend day set containing Friday and Saturday, (3) a
125/// transition at October 1, 2001 having a weekend day set containing only
126/// Friday, and (4) a transition at September 9, 2009 having a weekend day set
127/// containing Friday and Saturday. To represent the weekend days of the United
128/// States, a calendar having a range after 1940 can use a single weekend-days
129/// transition on January 1, 0001 containing Saturday and Sunday.
130///
131/// On construction, a calendar does not contain any weekend-days transitions.
132/// The `addWeekendDaysTransition` method adds a new weekend-days transition or
133/// replaces an existing weekend-days transition. The `addWeekendDay` and
134/// `addWeekendDays` methods create a weekend-days transition at January 1,
135/// 0001, if one doesn't already exist, and update the set of weekend days for
136/// that transition. `addWeekendDay` and `addWeekendDays` should only be used
137/// for calendars having a consistent set of weekend days throughout their
138/// entire range. The use of `addWeekendDay` and `addWeekendDays` is intended
139/// to be *mutually* *exclusive* to the use of `addWeekendDaysTransition`. As
140/// such, the behavior of using these two methods together with
141/// `addWeekendDaysTransition` is undefined.
142///
143/// ## Nested Iterators {#bdlt_packedcalendar-nested-iterators}
144///
145///
146/// Also provided are several STL-style `const` bidirectional iterators
147/// accessible as nested `typedef`s. `HolidayConstIterator`,
148/// `HolidayCodeConstIterator`, `WeekendDaysTransitionConstIterator`, and
149/// `BusinessDayConstIterator`, respectively, iterate over a chronologically
150/// ordered sequence of holidays, a numerically ordered sequence of holiday
151/// codes, a sequence of chronologically ordered weekend-days transitions, and a
152/// sequence of chronologically ordered business days. Reverse iterators are
153/// also provided for each of these (forward) iterators. As a general rule,
154/// calling a `const` method will not invalidate any iterators, and calling a
155/// non-`const` method might invalidate all of them; it is, however, guaranteed
156/// that attempting to add *duplicate* holidays or holiday codes will have no
157/// effect, and therefore will not invalidate any iterators. It is also
158/// guaranteed that adding a new code for an existing holiday will not
159/// invalidate any `HolidayConstIterator` objects.
160///
161/// Note that these iterators do *not* meet the requirements for a
162/// `bsl::forward_iterator` and should not be used in standard algorithms (e.g.,
163/// `bsl::lower_bound`).
164///
165/// ## Iterator Invalidation {#bdlt_packedcalendar-iterator-invalidation}
166///
167///
168/// The modification of a `bdlt::PackedCalendar` will invalidate iterators
169/// referring to the calendar. The following table shows the relationship
170/// between a calendar manipulator and the types of iterators it will
171/// invalidate if the invocation of the manipulator modified the calendar (e.g.,
172/// using `addHoliday` with a date that is not currently a holiday in the
173/// calendar):
174/// @code
175/// Manipulator Invalidates
176/// -------------------------- --------------------
177/// `operator=` H HC WDT BD
178/// `addHoliday` H HC BD
179/// `addHolidayCode` HC
180/// `addHolidayCodeIfInRange` HC
181/// `addHolidayIfInRange` H HC BD
182/// `addWeekendDay` WDT BD
183/// `addWeekendDays` WDT BD
184/// `addWeekendDaysTransition` WDT BD
185/// `intersectBusinessDays` H HC WDT BD
186/// `intersectNonBusinessDays` H HC WDT BD
187/// `removeAll` H HC WDT BD
188/// `removeHoliday` H HC BD
189/// `removeHolidayCode` HC
190/// `setValidRange` H HC BD
191/// `unionBusinessDays` H HC WDT BD
192/// `unionNonBusinessDays` H HC WDT BD
193///
194/// where "H" represents the holiday iterators (`HolidayConstIterator` and
195/// `HolidayConstReverseIterator`), "HC" represents the holiday code iterators
196/// (`HolidayCodeConstIterator` and `HolidayCodeConstReverseIterator`), "WDT"
197/// represents the weekend-days transition iterators
198/// (`WeekendDaysTransitionConstIterator` and
199/// `WeekendDaysTransitionConstReverseIterator`), and "BD" represents the
200/// business day iterators (`BusinessDayConstIterator` and
201/// `BusinessDayConstReverseIterator`).
202/// @endcode
203///
204/// ## Performance and Exception-Safety Guarantees {#bdlt_packedcalendar-performance-and-exception-safety-guarantees}
205///
206///
207/// The asymptotic worst-case performance of representative operations is
208/// characterized using big-O notation, `O[f(N,M,W,V)]`. `N` and `M` each refer
209/// to the combined number (`H + C`) of holidays `H` (i.e., method
210/// `numHolidays`) and holiday codes `C` (i.e., `numHolidayCodesTotal`) in the
211/// respective packed calendars. `W` and `V` each refer to the (likely small)
212/// number of weekend-days transitions in the respective packed calendars. For
213/// clarity, the methods have abbreviated arguments: `b`, `e`, and `d` are
214/// dates, `c` is a holiday code, `u` is a weekday, and `w` is a set of
215/// weekdays. Here, *Best* *Case* complexity, denoted by `B[f(N)]`, is loosely
216/// defined (for manipulators) as the worst-case cost, provided that (1) no
217/// additional internal capacity is required, (2) the start of the valid range
218/// does not change, and (3) that if a holiday (or holiday code) is being added,
219/// it is being appended *to* *the* *end* of the current sequence (of the latest
220/// holiday).
221/// @code
222/// Worst Best Exception-Safety
223/// Operation Case Case Guarantee
224/// --------- ----- ---- ----------------
225/// DEFAULT CTOR O[1] No-Throw
226/// COPY CTOR(N) O[N] Exception-Safe
227/// N.DTOR() O[1] No-Throw
228///
229/// N.OP=(M) O[M] Basic <*>
230///
231/// N.reserveCapacity(H, C) O[N] Strong <*>
232///
233/// N.setValidRange(b, e) O[N] O[1] Basic <*>
234/// N.addDay(d) O[N] O[1] Basic <*>
235/// N.addHoliday(d) O[N] O[1] Basic <*>
236/// N.addHolidayCode(d,c) O[N] O[1] Basic <*>
237///
238/// N.addWeekendDay(u) O[1] No-Throw
239/// N.addWeekendDaysTransition(d,w) O[W] Basic <*>
240///
241/// N.intersectBusinessDays(M) O[N+M+W+V] Basic <*>
242/// N.intersectNonBusinessDays(M) O[N+M+W+V] Basic <*>
243/// N.unionBusinessDays(M) O[N+M+W+V] Basic <*>
244/// N.unionNonBusinessDays(M) O[N+M+W+V] Basic <*>
245///
246/// N.removeHoliday(d) O[N] No-Throw
247/// N.removeHolidayCode(d, c) O[N] No-Throw
248/// N.removeAll(); O[1] No-Throw
249///
250/// N.swap(M) O[1] No-Throw
251///
252/// N.firstDate() O[1] No-Throw
253/// N.lastDate() O[1] No-Throw
254/// N.length() O[1] No-Throw
255///
256/// N.numHolidays() O[1] No-Throw
257///
258/// N.numHolidayCodesTotal() O[1] No-Throw
259/// N.numWeekendDaysInRange() O[1] No-Throw
260///
261/// N.isInRange(d); O[1] No-Throw
262/// N.isWeekendDay(w); O[1] No-Throw
263/// N.isWeekendDay(d) O[log(W)] No-Throw
264///
265/// N.isHoliday(d); O[log(N)] No_Throw
266/// N.isBusinessDay(d); O[log(N)] No_Throw
267/// N.isNonBusinessDay(d); O[log(N)] No_Throw
268///
269/// N.numHolidayCodes(d) O[log(N)] No-Throw
270///
271/// N.numBusinessDays() O[N] No-Throw
272/// N.numNonBusinessDays() O[N] No-Throw
273///
274/// other 'const' methods O[1] .. O[N] No-Throw
275///
276///
277/// OP==(N,M) O[min(N,M)+min(W+V) No-Throw
278/// OP!=(N,M) O[min(N,M)+min(W+V) No-Throw
279///
280/// <*> No-Throw guarantee when capacity is sufficient.
281/// @endcode
282/// Note that *all* of the non-creator methods of `bdlt::PackedCalendar` provide
283/// the *No-Throw* guarantee whenever sufficient capacity is already available.
284/// Also note that these are largely the same as `bdlt::Calendar` *except* that
285/// the accessors `isBusinessDay` and `isNonBusinessDay` are logarithmic in the
286/// number of holidays in `bdlt::PackedCalendar`.
287///
288/// ## Usage {#bdlt_packedcalendar-usage}
289///
290///
291/// The two subsections below illustrate various aspects of populating and using
292/// packed calendars.
293///
294/// ### Example 1: Populating Packed Calendars {#bdlt_packedcalendar-example-1-populating-packed-calendars}
295///
296///
297/// Packed calendars will typically be populated from a database or flat file.
298/// The user should employ an appropriate population mechanism that provides
299/// the desired holiday dates and associated holiday codes within some desired
300/// range. For example, suppose we have created the following flat-file format
301/// that encodes calendar information, including holidays and holiday codes (we
302/// assume, for the simplicity of this example, that "Weekend Days" (i.e.,
303/// recurring non-business days) are always just Saturdays and Sundays):
304/// @code
305/// // HOLIDAY DATE HOLIDAY CODES
306/// // ------------ -------------
307/// // Year Mon Day # Codes Comments, separated by Semicolons (;)
308/// // ---- --- --- --- --------- -------------------------------------
309/// 2010 1 18 1 57 ;Martin Luther King, Jr. Day
310/// 2010 2 15 1 51 ;Presidents Day
311/// 2010 4 2 2 9 105 ;Easter Sunday (Observed); Good Friday
312/// 2010 5 31 1 16 ;Memorial Day
313/// 2010 7 5 1 28 ;Independence Day (Observed)
314/// 2010 9 6 1 44 ;Labor Day
315/// 2010 10 11 1 19 ;Columbus Day
316/// 2010 11 2 0 ;Election Day
317/// 2010 11 25 1 14 ;Thanksgiving Day
318/// 2010 12 25 1 4 ;Christmas Day (Observed)
319/// 2010 12 31 1 22 ;New Year's Day (Observed)
320/// @endcode
321/// Let's now create a couple of primitive helper functions to extract holiday
322/// and holiday-code counts from a given input stream.
323///
324/// First, we'll create a helper function to get a holiday record:
325/// @code
326/// /// Load into the specified `holiday` the date of the next holiday, and
327/// /// into the specified `numCodes` the associated number of holiday codes
328/// /// for the holiday read from the specified `input` stream. Return 0 on
329/// /// success, and a non-zero value (with no effect on `*holiday` and
330/// /// `*numCodes`) otherwise.
331/// int getNextHoliday(bsl::istream& input, bdlt::Date *holiday, int *numCodes)
332/// {
333/// enum { SUCCESS = 0, FAILURE = 1 };
334///
335/// int year, month, day, codes;
336///
337/// if (input.good()) {
338/// input >> year;
339/// }
340/// if (input.good()) {
341/// input >> month;
342/// }
343/// if (input.good()) {
344/// input >> day;
345/// }
346/// if (input.good()) {
347/// input >> codes;
348/// }
349///
350/// if (input.good()
351/// && bdlt::Date::isValidYearMonthDay(year, month, day)) {
352/// *holiday = bdlt::Date(year, month, day);
353/// *numCodes = codes;
354/// return SUCCESS; // RETURN
355/// }
356///
357/// return FAILURE; // RETURN
358/// }
359/// @endcode
360/// Then, we'll write a function that gets us an integer holiday code, or
361/// invalidates the stream if it cannot (note that negative holiday codes are
362/// not supported by this function, but negative holiday codes *are* supported
363/// by `bdlt::PackedCalendar`):
364/// @code
365/// /// Load, into the specified `result`, the value read from the specified
366/// /// `input` stream. If the next token is not an integer, invalidate the
367/// /// stream with no effect on `result`.
368/// void getNextHolidayCode(bsl::istream& input, int *result)
369/// {
370/// int holidayCode;
371///
372/// if (input.good()) {
373/// input >> holidayCode;
374/// }
375///
376/// if (input.good()) {
377/// *result = holidayCode;
378/// }
379/// }
380/// @endcode
381/// Now, with these helper functions, it is a simple matter to write a calendar
382/// loader function, `load`, that populates a given calendar with data in this
383/// "proprietary" format:
384/// @code
385/// /// Populate the specified `calendar` with holidays and corresponding
386/// /// codes read from the specified `input` stream in our "proprietary"
387/// /// format (see above). On success, `input` will be empty, but valid;
388/// /// otherwise `input` will be invalid.
389/// void load(bsl::istream& input, bdlt::PackedCalendar *calendar)
390/// {
391/// bdlt::Date holiday;
392/// int numCodes;
393///
394/// while (0 == getNextHoliday(input, &holiday, &numCodes)) {
395/// calendar->addHoliday(holiday); // add date
396/// for (int i = 0; i < numCodes; ++i) {
397/// int holidayCode = 0;
398/// getNextHolidayCode(input, &holidayCode);
399/// if (input.good()) {
400/// // add codes
401///
402/// calendar->addHolidayCode(holiday, holidayCode);
403/// }
404/// }
405/// input.ignore(256, '\n'); // skip comments
406/// }
407/// }
408/// @endcode
409/// Finally, we load a `bdlt::PackedCalendar` and verify some values from the
410/// calendar.
411/// @code
412/// bsl::stringstream stream;
413/// {
414/// stream << "2010 9 6 1 44 ;Labor Day\n"
415/// << "2010 10 11 1 19 ;Columbus Day\n"
416/// << "2010 11 2 0 ;Election Day\n"
417/// << "2010 11 25 1 14 ;Thanksgiving Day\n";
418/// }
419///
420/// bdlt::PackedCalendar calendar;
421/// load(stream, &calendar);
422///
423/// assert(bdlt::Date(2010, 9, 6) == calendar.firstDate());
424/// assert(bdlt::Date(2010, 11, 25) == calendar.lastDate());
425/// assert(true == calendar.isBusinessDay(bdlt::Date(2010, 10, 12)));
426/// assert(false == calendar.isBusinessDay(bdlt::Date(2010, 11, 2)));
427/// @endcode
428/// Note that different formats can easily be accommodated, while still using
429/// the same basic population strategy. Also note that it may be substantially
430/// more efficient to populate calendars in increasing date order, compared to
431/// either reverse or random order.
432///
433/// ### Example 2: Using Packed Calendars {#bdlt_packedcalendar-example-2-using-packed-calendars}
434///
435///
436/// Higher-level clients (e.g., a GUI) may need to extract the holiday codes
437/// for a particular date, use them to look up their corresponding string names
438/// in a separate repository (e.g., a vector of strings), and to display these
439/// names to end users.
440///
441/// First, let's create a function that prints the names of holidays for a
442/// given date:
443/// @code
444/// /// Write, to the specified `output` stream, the elements in the
445/// /// specified `holidayNames` associated, via holiday codes in the
446/// /// specified `calendar`, to the specified `date`. Each holiday name
447/// /// emitted is followed by a newline (`\n`). The behavior is undefined
448/// /// unless `date` is within the valid range of `calendar`.
449/// void
450/// printHolidayNamesForGivenDate(bsl::ostream& output,
451/// const bdlt::PackedCalendar& calendar,
452/// const bdlt::Date& date,
453/// const bsl::vector<bsl::string>& holidayNames)
454/// {
455/// for (bdlt::PackedCalendar::HolidayCodeConstIterator
456/// it = calendar.beginHolidayCodes(date);
457/// it != calendar.endHolidayCodes(date);
458/// ++it) {
459/// output << holidayNames[*it] << bsl::endl;
460/// }
461/// }
462/// @endcode
463/// Then, since we can write the names of holidays for a given date, let's
464/// write a function that can write out all of the names associated with each
465/// holiday in the calendar:
466/// @code
467/// /// Write, to the specified `output` stream, each date associated with
468/// /// a holiday in the specified `calendar` followed by any elements in
469/// /// the specified `holidayNames` (associated via holiday codes in
470/// /// `calendar`) corresponding to that date. Each date emitted is
471/// /// preceded and followed by a newline (`\n`). Each holiday name
472/// /// emitted is followed by a newline (`\n`).
473/// void
474/// printHolidayDatesAndNames(bsl::ostream& output,
475/// const bdlt::PackedCalendar& calendar,
476/// const bsl::vector<bsl::string>& holidayNames)
477/// {
478/// for (bdlt::PackedCalendar::HolidayConstIterator
479/// it = calendar.beginHolidays();
480/// it != calendar.endHolidays(); ++it) {
481/// output << '\n' << *it << '\n';
482/// printHolidayNamesForGivenDate(output,
483/// calendar,
484/// *it,
485/// holidayNames);
486/// }
487/// }
488/// @endcode
489/// Next, we populate the `holidayNames` vector:
490/// @code
491/// bsl::vector<bsl::string> holidayNames;
492/// {
493/// holidayNames.resize(45);
494///
495/// holidayNames[44] = "Labor Day"; // holiday code 44 is for
496/// // Labor Day
497///
498/// holidayNames[14] = "Thanksgiving Day"; // holiday code 14 is for
499/// // Thanksgiving Day
500/// }
501/// @endcode
502/// Now, using the `calendar` populated in the previous example, we print the
503/// holiday information to a new `bsl::stringstream`:
504/// @code
505/// bsl::stringstream printStream;
506///
507/// printHolidayDatesAndNames(printStream, calendar, holidayNames);
508/// @endcode
509/// Finally, we verify the output:
510/// @code
511/// assert(printStream.str() == "\n06SEP2010\nLabor Day\n\n11OCT2010\n\n\n"
512/// "02NOV2010\n\n25NOV2010\nThanksgiving Day\n");
513/// @endcode
514/// @}
515/** @} */
516/** @} */
517
518/** @addtogroup bdl
519 * @{
520 */
521/** @addtogroup bdlt
522 * @{
523 */
524/** @addtogroup bdlt_packedcalendar
525 * @{
526 */
527
528#include <bdlscm_version.h>
529
531#include <bdlt_date.h>
532#include <bdlt_dayofweek.h>
533#include <bdlt_dayofweekset.h>
534
535#include <bdlc_packedintarray.h>
537
538#include <bslalg_swaputil.h>
539
540#include <bslh_hash.h>
541
542#include <bslma_allocator.h>
544
546
547#include <bsls_assert.h>
548#include <bsls_preconditions.h>
549#include <bsls_review.h>
550
551#include <bsl_cstddef.h>
552#include <bsl_iosfwd.h>
553#include <bsl_iterator.h>
554#include <bsl_utility.h> // 'bsl::pair'
555#include <bsl_vector.h>
556
557#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
558#include <bslalg_typetraits.h>
559
560#include <bsl_algorithm.h>
561#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
562
563
564namespace bdlt {
565
566class PackedCalendar_BusinessDayConstIterator;
567class PackedCalendar_HolidayCodeConstIterator;
568class PackedCalendar_HolidayConstIterator;
569
570 // ====================
571 // class PackedCalendar
572 // ====================
573
574/// This class implements a space-efficient, value-semantic repository of
575/// weekend and holiday information over a *valid* *range* of dates. This
576/// valid range, `[firstDate() .. lastDate()]`, spans the first and last
577/// dates of a calendar's accessible contents. A calendar can be
578/// "populated" with weekend and holiday information via a suite of "add"
579/// methods. Any subset of days of the week may be specified as weekend
580/// (i.e., recurring non-business) days starting from a specified date by
581/// adding a weekend-days transition; holidays within the valid range are
582/// specified individually. When adding a holiday, an arbitrary integer
583/// "holiday code" may be associated with that date. Additional holiday
584/// codes for that date may subsequently be added. Both the holidays and
585/// the set of unique holiday codes associated with each holiday date are
586/// maintained (internally) in order of increasing value. Note that the
587/// behavior of requesting *any* calendar information for a supplied date
588/// whose value is outside the current *valid* *range* for that calendar
589/// (unless otherwise noted, e.g., `isWeekendDay`) is undefined.
590///
591/// See @ref bdlt_packedcalendar
593
594 private:
595 // PRIVATE TYPES
597
601
604
605 /// This `struct` provides a comparator predicate for the type
606 /// `WeekendDaysTransition` to enable the use of standard algorithms
607 /// (such as `bsl::lower_bound`) on ranges of objects of that type.
608 struct WeekendDaysTransitionLess {
609
610 // ACCESSORS
611
612 /// Return `true` if the value of the specified `lhs` is less than
613 /// (ordered before) the value of the specified `rhs`, and `false`
614 /// otherwise. The value of `lhs` is less than the value of `rhs`
615 /// if the date represented by the data member `first` of `lhs` is
616 /// earlier than the date represented by the data member `first` of
617 /// `rhs`.
618 bool operator()(const WeekendDaysTransitionPrivate& lhs,
619 const WeekendDaysTransitionPrivate& rhs) const
620 {
621 return lhs.first < rhs.first;
622 }
623 };
624
625 public:
626 // TYPES
628
630
632
634
637
640
643
646
647 typedef
648 bsl::reverse_iterator<WeekendDaysTransitionSequence::const_iterator>
650
651 private:
652 // DATA
653 Date d_firstDate; // first valid date of calendar or
654 // 9999/12/31 if this calendar is
655 // empty
656
657 Date d_lastDate; // last valid date of calendar or
658 // 0001/01/01 if this calendar is
659 // empty
660
662 d_weekendDaysTransitions;
663 // chronological list of weekend-
664 // days transitions
665
666 bdlc::PackedIntArray<int> d_holidayOffsets;
667 // ordered list of all holidays in
668 // this calendar stored as offsets
669 // from 'd_firstDate'
670
671 bdlc::PackedIntArray<int> d_holidayCodesIndex;
672 // parallel to 'd_holidayOffsets',
673 // this is a list of indices into
674 // 'd_holidayCodes'; note that the
675 // end of each sequence can be
676 // determined using the value of
677 // the next entry in this array if
678 // it exists, or else the length
679 // of 'd_holidayCodes' itself
680
681 bdlc::PackedIntArray<int> d_holidayCodes;
682 // sequences of holiday codes,
683 // each partitioned into an
684 // ordered "chunk" of codes per
685 // holiday in 'd_holidayOffsets';
686 // chunks are stored in the same
687 // order as in 'd_holidayOffsets'
688
689 bslma::Allocator *d_allocator_p;
690 // memory allocator (held, not
691 // owned)
692
693 // FRIENDS
695
696 friend bool operator==(const PackedCalendar&, const PackedCalendar&);
697 friend bool operator!=(const PackedCalendar&, const PackedCalendar&);
698 template <class HASHALG>
699 friend void hashAppend(HASHALG& hashAlg, const PackedCalendar&);
700
701 private:
702 // PRIVATE CLASS METHODS
703
704 /// Append, onto the specified `resHolidayOffsets`,
705 /// `resHolidayCodesIndex`, and `resHolidayCodes`, the intersection of
706 /// the holidays from the specified `lhs` and `rhs` calendars
707 /// restricted to the date range of the specified `firstDate` and
708 /// `lastDate`. The behavior is undefined unless
709 /// `firstDate <= lastDate`.
710 static void intersectHolidays(
711 bdlc::PackedIntArray<int> *resHolidayOffsets,
712 bdlc::PackedIntArray<int> *resHolidayCodesIndex,
713 bdlc::PackedIntArray<int> *resHolidayCodes,
714 const PackedCalendar& lhs,
715 const PackedCalendar& rhs,
716 const bdlt::Date firstDate,
717 const bdlt::Date lastDate);
718
719 /// Append, onto the specified `resHolidayOffsets`,
720 /// `resHolidayCodesIndex`, and `resHolidayCodes`, the union of the
721 /// holidays from the specified `lhs` and `rhs` calendars restricted to
722 /// the date range of the specified `firstDate` and `lastDate`. The
723 /// behavior is undefined unless `firstDate <= lastDate`.
724 static void unionHolidays(bdlc::PackedIntArray<int> *resHolidayOffsets,
725 bdlc::PackedIntArray<int> *resHolidayCodesIndex,
726 bdlc::PackedIntArray<int> *resHolidayCodes,
727 const PackedCalendar& lhs,
728 const PackedCalendar& rhs,
729 const bdlt::Date firstDate,
730 const bdlt::Date lastDate);
731
732 // PRIVATE MANIPULATORS
733
734 /// Add the specified `offset` as a holiday offset in this calendar. If
735 /// the date represented by `offset` is already a holiday, this method
736 /// has no effect. Return the index of `d_holidayOffsets` where
737 /// `offset` is stored. The behavior is undefined unless `0 <= offset`
738 /// and the `offset` represents a date within the valid range of the
739 /// calendar.
740 int addHolidayImp(int offset);
741
742 // PRIVATE ACCESSORS
743
744 /// Return an iterator that refers to the first non-modifiable holiday
745 /// code for the holiday referenced by the specified `iter`. If there
746 /// are no holiday codes associated with the date referenced by `iter`,
747 /// the returned iterator has the same value as that returned by
748 /// `endHolidayCodes(iter)`. The behavior is undefined unless `iter`
749 /// refers to a valid holiday of this calendar.
750 CodesConstIterator beginHolidayCodes(
751 const OffsetsConstIterator& iter) const;
752
753 /// Return an iterator that indicates the element one past the last
754 /// holiday code associated with the date referenced by the specified
755 /// `iter`. The behavior is undefined unless `iter` references a valid
756 /// holiday in this calendar.
757 CodesConstIterator endHolidayCodes(const OffsetsConstIterator& iter) const;
758
759 public:
760 // CLASS METHODS
761
762 // Aspects
763
764 /// Return the maximum valid BDEX format version, as indicated by the
765 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
766 /// method. Note that it is highly recommended that `versionSelector`
767 /// be formatted as "YYYYMMDD", a date representation. Also note that
768 /// `versionSelector` should be a *compile*-time-chosen value that
769 /// selects a format version supported by both externalizer and
770 /// unexternalizer. See the `bslx` package-level documentation for more
771 /// information on BDEX streaming of value-semantic types and
772 /// containers.
773 static int maxSupportedBdexVersion(int versionSelector);
774
775 // CREATORS
776
777 /// Create an empty calendar, i.e., a calendar having an empty valid
778 /// range. Optionally specify a `basicAllocator` used to supply memory.
779 /// If `basicAllocator` is 0, the currently installed default allocator
780 /// is used.
781 explicit PackedCalendar(bslma::Allocator *basicAllocator = 0);
782
783 /// Create a calendar having a valid range from the specified
784 /// `firstDate` through the specified `lastDate`. Optionally specify a
785 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
786 /// the currently installed default allocator is used. The behavior is
787 /// undefined unless `firstDate <= lastDate`.
789 const Date& lastDate,
790 bslma::Allocator *basicAllocator = 0);
791
792 /// Create a calendar having the value of the specified `original`
793 /// calendar. Optionally specify a `basicAllocator` used to supply
794 /// memory. If `basicAllocator` is 0, the currently installed default
795 /// allocator is used.
797 bslma::Allocator *basicAllocator = 0);
798
799 /// Destroy this object.
801
802 // MANIPULATORS
803
804 /// Assign to this calendar the value of the specified `rhs` calendar,
805 /// and return a reference providing modifiable access to this calendar.
806 /// See {Iterator Invalidation} for information regarding which
807 /// iterators are affected by the use of this method.
809
810 /// Extend the valid range (if necessary) of this calendar to include
811 /// the specified `date` value.
812 void addDay(const Date& date);
813
814 /// Mark the specified `date` as a holiday (i.e., a non-business day)
815 /// in this calendar. Extend the valid range of this calendar if
816 /// necessary. If `date` is already marked as a holiday, this method
817 /// has no effect. See {Iterator Invalidation} for information
818 /// regarding which iterators are affected by the use of this method.
819 void addHoliday(const Date& date);
820
821 /// Mark the specified `date` as a holiday (i.e., a non-business day) in
822 /// this calendar and add the specified `holidayCode` (if not already
823 /// present) to the ordered set of codes associated with `date`.
824 /// Extend the valid range of this calendar if necessary. If
825 /// `holidayCode` is already a code for `date`, this method has no
826 /// effect. See {Iterator Invalidation} for information regarding
827 /// which iterators are affected by the use of this method.
828 void addHolidayCode(const Date& date, int holidayCode);
829
830 /// Mark the specified `date` as a holiday (i.e., a non-business day)
831 /// in this calendar and add the specified `holidayCode` (if not
832 /// already present) to the set of codes associated with `date`, if
833 /// `date` is within the valid range of this calendar. Return 0 if
834 /// `date` is in range, and a non-zero value otherwise. If
835 /// `holidayCode` is already a code for `date`, or if `date` is not in
836 /// the valid range, this method has no effect. See
837 /// {Iterator Invalidation} for information regarding which iterators
838 /// are affected by the use of this method. Note that this method may
839 /// be called repeatedly with the same value for `date` to build up a
840 /// set of holiday codes for that date.
841 int addHolidayCodeIfInRange(const Date& date, int holidayCode);
842
843 /// Mark the specified `date` as a holiday (i.e., a non-business day) in
844 /// this calendar if `date` is within the valid range. Return 0 if
845 /// `date` is in range, and a non-zero value otherwise. This method has
846 /// no effect if `date` is already marked as a holiday or is not in the
847 /// valid range. See {Iterator Invalidation} for information regarding
848 /// which iterators are affected by the use of this method.
849 int addHolidayIfInRange(const Date& date);
850
851 /// Add the specified `weekendDay` to the set of weekend days associated
852 /// with the weekend-days transition at January 1, 0001 maintained by
853 /// this calendar. Create a transition at January 1, 0001 if one does
854 /// not exist. See {Iterator Invalidation} for information regarding
855 /// which iterators are affected by the use of this method. The
856 /// behavior is undefined unless no weekend-days transitions were added
857 /// to this calendar via the `addWeekendDaysTransition` method.
859
860 /// Add the specified `weekendDays` to the set of weekend days
861 /// associated with the weekend-days transition at January 1, 0001
862 /// maintained by this calendar. Create a transition at January 1, 0001
863 /// if one does not exist. See {Iterator Invalidation} for information
864 /// regarding which iterators are affected by the use of this method.
865 /// The behavior is undefined unless no weekend-days transitions were
866 /// added to this calendar via the `addWeekendDaysTransition` method.
867 void addWeekendDays(const DayOfWeekSet& weekendDays);
868
869 /// Add to this calendar a weekend-days transition on the specified
870 /// `startDate` having the specified `weekendDays` set. If a
871 /// weekend-days transition already exists on `startDate`, replace the
872 /// set of weekend days of that transition with `weekendDays`. See
873 /// {Iterator Invalidation} for information regarding which iterators
874 /// are affected by the use of this method. Note that this method does
875 /// not extend the valid range of the calendar.
876 void addWeekendDaysTransition(const Date& startDate,
877 const DayOfWeekSet& weekendDays);
878
879 /// Merge the specified `other` calendar into this calendar such that
880 /// the valid range of this calendar becomes the *intersection* of the
881 /// two calendars' ranges, and the weekend days and holidays for this
882 /// calendar become the union of those (non-business) days from the two
883 /// calendars -- i.e., the valid business days of this calendar become
884 /// the intersection of those of the two original calendar values over
885 /// the *intersection* of their ranges. For each holiday that remains,
886 /// the resulting holiday codes in this calendar will be the union of
887 /// the corresponding original holiday codes. See
888 /// {Iterator Invalidation} for information regarding which iterators
889 /// are affected by the use of this method.
891
892 /// Merge the specified `other` calendar into this calendar such that
893 /// the valid range of this calendar becomes the *intersection* of the
894 /// two calendars' ranges, the weekend days for this calendar become the
895 /// intersection of those days from the two calendars, and the holidays
896 /// for this calendar become the set of days that are a holiday in one
897 /// of the calendars and a non-business day in the other calendar --
898 /// i.e., the valid business days of this calendar become the union of
899 /// those of the two original calendars over the *intersection* of their
900 /// ranges. For each holiday that remains, the resulting holiday codes
901 /// in this calendar will be the union of the corresponding original
902 /// holiday codes. See {Iterator Invalidation} for information
903 /// regarding which iterators are affected by the use of this method.
905
906 /// Remove all information from this calendar, leaving it with its
907 /// default constructed "empty" value. See {Iterator Invalidation} for
908 /// information regarding which iterators are affected by the use of
909 /// this method.
910 void removeAll();
911
912 /// Remove from this calendar the holiday having the specified `date` if
913 /// such a holiday exists. This operation has no effect if `date` is
914 /// not a holiday in this calendar. See {Iterator Invalidation} for
915 /// information regarding which iterators are affected by the use of
916 /// this method. Note that this method is defined for all `date`
917 /// values, not just those that fall within the valid range, and may be
918 /// invoked even on an empty calendar (i.e., having `0 == length()`).
919 void removeHoliday(const Date& date);
920
921 /// Remove from this calendar the specified `holidayCode` for the
922 /// holiday having the specified `date` if such a holiday having
923 /// `holidayCode` exists. This operation has no effect if `date` is not
924 /// a holiday in this calendar, or if the holiday at `date` does not
925 /// have `holidayCode` associated with it. See {Iterator Invalidation}
926 /// for information regarding which iterators are affected by the use of
927 /// this method. Note that this method is defined for all `date`
928 /// values, not just those that fall within the valid range, and may be
929 /// invoked even on an empty calendar (i.e., having `0 == length()`).
930 void removeHolidayCode(const Date& date, int holidayCode);
931
932 /// Reserve enough space to store at least the specified `numHolidays`
933 /// within this calendar. This method has no effect if
934 /// `numHolidays <= numHolidays()`.
936
937 /// Reserve enough space to store at least the specified
938 /// `numHolidayCodes` within this calendar assuming no additional
939 /// holidays are added to this calendar. This method has no effect if
940 /// `numHolidayCodes <= numHolidayCodesTotal()`.
942
943 /// Set the range of this calendar using the specified `firstDate` and
944 /// `lastDate` as, respectively, the first date and the last date of the
945 /// calendar. Any holiday that is outside the new range and its holiday
946 /// codes are removed. See {Iterator Invalidation} for information
947 /// regarding which iterators are affected by the use of this method.
948 /// The behavior is undefined unless `firstDate <= lastDate`.
950
951 /// Merge the specified `other` calendar into this calendar such that
952 /// the valid range of this calendar becomes the *union* of the two
953 /// calendars' ranges (or the minimal continuous range spanning the two
954 /// ranges, if the ranges are non-overlapping), the weekend days for
955 /// this calendar become the intersection of those days from the two
956 /// calendars, and the holidays for this calendar become the set of days
957 /// that are a holiday in one of the calendars and a non-business day in
958 /// the other calendar -- i.e., the valid business days of this calendar
959 /// become the union of those of the two original calendar values. For
960 /// each holiday that remains, the resulting holiday codes in this
961 /// calendar will be the union of the corresponding original holiday
962 /// codes. See {Iterator Invalidation} for information regarding which
963 /// iterators are affected by the use of this method.
965
966 /// Merge the specified `other` calendar into this calendar such that
967 /// the valid range of this calendar becomes the *union* of the two
968 /// calendars' ranges (or the minimal continuous range spanning the two
969 /// ranges, if the ranges are non-overlapping), and the weekend days
970 /// and holidays for this calendar become the union of those
971 /// (non-business) days from the two calendars -- i.e., the valid
972 /// business days of this calendar become the intersection of those of
973 /// the two calendars after each range is extended to cover the
974 /// resulting one. For each holiday in either calendar, the resulting
975 /// holiday codes in this calendar will be the union of the
976 /// corresponding original holiday codes. See {Iterator Invalidation}
977 /// for information regarding which iterators are affected by the use of
978 /// this method.
980
981 // Aspects
982
983 /// Assign to this object the value read from the specified input
984 /// `stream` using the specified `version` format and return a reference
985 /// to the modifiable `stream`. If `stream` is initially invalid, this
986 /// operation has no effect. If `stream` becomes invalid during this
987 /// operation or if `version` is not supported, this object is
988 /// unaltered. Note that no version is read from `stream`. See the
989 /// `bslx` package-level documentation for more information on BDEX
990 /// streaming of value-semantic types and containers.
991 template <class STREAM>
992 STREAM& bdexStreamIn(STREAM& stream, int version);
993
994 /// Efficiently exchange the value of this object with the value of the
995 /// specified `other` object. This method provides the no-throw
996 /// exception-safety guarantee. The behavior is undefined unless this
997 /// object was created with the same allocator as `other`.
998 void swap(PackedCalendar& other);
999
1000 // ACCESSORS
1001
1002 /// Return an iterator providing non-modifiable access to the first
1003 /// business day in this calendar. If this calendar has no valid
1004 /// business days, the returned iterator has the same value as that
1005 /// returned by `endBusinessDays()`.
1007
1008 /// Return an iterator providing non-modifiable access to the first
1009 /// business day that occurs on or after the specified `date` in this
1010 /// calendar. If this calendar has no such business day, the returned
1011 /// iterator has the same value as that returned by
1012 /// `endBusinessDays(date)`. The behavior is undefined unless `date` is
1013 /// within the valid range of this calendar.
1015
1016 /// Return an iterator providing non-modifiable access to the first
1017 /// holiday code for the specified `date` in this calendar. If there is
1018 /// no holiday code associated with `date`, the returned iterator has
1019 /// the same value as that returned by `endHolidayCodes(date)`. The
1020 /// behavior is undefined unless `date` is marked as a holiday in this
1021 /// calendar.
1023
1024 /// Return an iterator providing non-modifiable access to the first
1025 /// holiday code for the holiday referenced by the specified `iter`. If
1026 /// there is no holiday code associated with the date referenced by
1027 /// `iter`, the returned iterator has the same value as that returned by
1028 /// `endHolidayCodes(iter)`. The behavior is undefined unless `iter`
1029 /// refers to a valid holiday of this calendar.
1030 HolidayCodeConstIterator beginHolidayCodes(
1031 const HolidayConstIterator& iter) const;
1032
1033 /// Return an iterator providing non-modifiable access to the first
1034 /// holiday in this calendar. If this calendar has no holidays, the
1035 /// returned iterator has the same value as that returned by
1036 /// `endHolidays()`.
1038
1039 /// Return an iterator providing non-modifiable access to the first
1040 /// holiday that occurs on or after the specified `date` in this
1041 /// calendar. If this calendar has no such holiday, the returned
1042 /// iterator has the same value as that returned by `endHolidays(date)`.
1043 /// The behavior is undefined unless `date` is within the valid range
1044 /// of this calendar.
1045 HolidayConstIterator beginHolidays(const Date& date) const;
1046
1047 /// Return an iterator providing non-modifiable access to the first
1048 /// weekend-days transition in the chronological sequence of
1049 /// weekend-days transitions maintained by this calendar. If this
1050 /// calendar has no weekend-days transitions, the returned iterator has
1051 /// the same value as that returned by `endWeekendDaysTransitions()`.
1053
1054 /// Return an iterator providing non-modifiable access to the
1055 /// past-the-end business day in this calendar.
1057
1058 /// Return an iterator providing non-modifiable access to the first
1059 /// business day that occurs after the specified `date` in this
1060 /// calendar. If this calendar has no such business day, the returned
1061 /// iterator has the same value as that returned by
1062 /// `endBusinessDays()`. The behavior is undefined unless `date` is
1063 /// within the valid range of this calendar.
1065
1066 /// Return an iterator providing non-modifiable access to the
1067 /// past-the-end holiday code associated with the specified `date`. The
1068 /// behavior is undefined unless `date` is marked as a holiday in this
1069 /// calendar.
1071
1072 /// Return an iterator providing non-modifiable access to the
1073 /// past-the-end holiday code associated with the date referenced by
1074 /// the specified `iter`. The behavior is undefined unless `iter`
1075 /// references a valid holiday in this calendar.
1077 endHolidayCodes(const HolidayConstIterator& iter) const;
1078
1079 /// Return an iterator providing non-modifiable access to the
1080 /// past-the-end holiday in the chronological sequence of holidays
1081 /// maintained by this calendar.
1083
1084 /// Return an iterator providing non-modifiable access to the first
1085 /// holiday that occurs after the specified `date` in this calendar.
1086 /// If this calendar has no such holiday, the returned iterator has the
1087 /// same value as that returned by `endHolidays()`. The behavior is
1088 /// undefined unless `date` is within the valid range of this calendar.
1089 HolidayConstIterator endHolidays(const Date& date) const;
1090
1091 /// Return an iterator providing non-modifiable access to the
1092 /// past-the-end weekend-days transition in the chronological sequence
1093 /// of weekend-days transitions maintained by this calendar.
1095
1096 /// Return a reference providing non-modifiable access to the earliest
1097 /// date in the valid range of this calendar. The behavior is
1098 /// undefined unless this calendar is non-empty -- i.e., unless
1099 /// `1 <= length()`.
1100 const Date& firstDate() const;
1101
1102 /// Load, into the specified `nextBusinessDay`, the date of the first
1103 /// business day in this calendar following the specified `date`.
1104 /// Return 0 on success -- i.e., if such a business day exists, and a
1105 /// non-zero value (with no effect on `nextBusinessDay`) otherwise. The
1106 /// behavior is undefined unless `date + 1` is both a valid `bdlt::Date`
1107 /// and within the valid range of this calendar.
1108 int getNextBusinessDay(Date *nextBusinessDay, const Date& date) const;
1109
1110 /// Load, into the specified `nextBusinessDay`, the date of the
1111 /// specified `nth` business day in this calendar following the
1112 /// specified `date`. Return 0 on success -- i.e., if such a business
1113 /// day exists, and a non-zero value (with no effect on
1114 /// `nextBusinessDay`) otherwise. The behavior is undefined unless
1115 /// `date + 1` is both a valid `bdlt::Date` and within the valid range
1116 /// of this calendar, and `0 < nth`.
1117 int getNextBusinessDay(Date *nextBusinessDay,
1118 const Date& date,
1119 int nth) const;
1120
1121 /// Return the holiday at the specified `index` in this calendar. For
1122 /// all `index` values from 0 to `numHolidays() - 1` (inclusive), a
1123 /// unique holiday is returned. The mapping of `index` to holiday is
1124 /// invalidated when the set of holidays is modified by an invocation of
1125 /// `addHoliday`, `addHolidayIfInRange`, `intersectBusinessDays`,
1126 /// `intersectNonBusinessDays`, `removeAll`, `removeHoliday`,
1127 /// `setValidRange`, `unionBusinessDays`, or `unionNonBusinessDays`.
1128 /// The behavior is undefined unless `0 <= index < numHolidays()`.
1129 bdlt::Date holiday(int index) const;
1130
1131 /// Return, for the holiday at the specified `date` in this calendar,
1132 /// the holiday code at the specified `index`. For all `index` values
1133 /// from 0 to `numHolidayCodes(date) - 1` (inclusive), a unique holiday
1134 /// code is returned. The mapping of `index` to holiday code is
1135 /// invalidated when the set of holidays or holiday codes is modified by
1136 /// an invocation of `addHoliday`, `addHolidayCode`,
1137 /// `addHolidayCodeIfInRange`, `addHolidayIfInRange`,
1138 /// `intersectBusinessDays`, `intersectNonBusinessDays`, `removeAll`,
1139 /// `removeHoliday`, `removeHolidayCode`, `setValidRange`,
1140 /// `unionBusinessDays`, or `unionNonBusinessDays`. The behavior is
1141 /// undefined unless `date` is a holiday in this calendar and
1142 /// `0 <= index < numHolidayCodes(date)`. Note that this method
1143 /// facilitates testing and generally should not be used by clients; in
1144 /// particular, using this method to iterate over the holiday codes for
1145 /// `date` is less efficient than using a `HolidayCodeConstIterator`.
1146 int holidayCode(const Date& date, int index) const;
1147
1148 /// Return `true` if the specified `date` is a business day (i.e., not
1149 /// a holiday or weekend day) in this calendar, and `false` otherwise.
1150 /// The behavior is undefined unless `date` is within the valid range of
1151 /// this calendar.
1152 bool isBusinessDay(const Date& date) const;
1153
1154 /// Return `true` if the specified `date` is a holiday in this calendar,
1155 /// and `false` otherwise. The behavior is undefined unless `date` is
1156 /// within the valid range of this calendar.
1157 bool isHoliday(const Date& date) const;
1158
1159 /// Return `true` if the specified `date` is within the valid range of
1160 /// this calendar (i.e., `firstDate() <= date <= lastDate()`), and
1161 /// `false` otherwise. Note that the valid range for a
1162 /// `PackedCalendar` is empty if its length is 0.
1163 bool isInRange(const Date& date) const;
1164
1165 /// Return `true` if the specified `date` is not a business day (i.e.,
1166 /// is either a holiday or weekend day) in this calendar, and `false`
1167 /// otherwise. The behavior is undefined unless `date` is within the
1168 /// valid range of this calendar. Note that:
1169 /// @code
1170 /// !isBusinessDay(date)
1171 /// @endcode
1172 /// returns the same result.
1173 bool isNonBusinessDay(const Date& date) const;
1174
1175 /// Return `true` if the specified `date` falls on a day of the week
1176 /// that is considered a weekend day in this calendar, and `false`
1177 /// otherwise. Note that this method is defined for all `date` values,
1178 /// not just those that fall within the valid range, and may be invoked
1179 /// even on an empty calendar (i.e., having `0 == length()`).
1180 bool isWeekendDay(const Date& date) const;
1181
1182 /// Return `true` if the specified `dayOfWeek` is a weekend day in this
1183 /// calendar, and `false` otherwise. The behavior is undefined unless
1184 /// no weekend-days transitions were added to this calendar via the
1185 /// `addWeekendDaysTransition` method.
1186 bool isWeekendDay(DayOfWeek::Enum dayOfWeek) const;
1187
1188 /// Return a reference providing non-modifiable access to the latest
1189 /// date in the valid range of this calendar. The behavior is
1190 /// undefined unless this calendar is non-empty -- i.e., unless
1191 /// `1 <= length()`.
1192 const Date& lastDate() const;
1193
1194 /// Return the number of days in the valid range of this calendar,
1195 /// which is defined to be 0 if this calendar is empty, and
1196 /// `lastDate() - firstDate() + 1` otherwise.
1197 int length() const;
1198
1199 /// Return the number of days in the valid range of this calendar that
1200 /// are considered business days -- i.e., are neither holidays nor
1201 /// weekend days. Note that
1202 /// `numBusinessDays() == length() - numNonBusinessDays()`.
1203 int numBusinessDays() const;
1204
1205 /// Return the number of days in the specified range
1206 /// `[beginDate .. endDate]` of this calendar that are considered
1207 /// business days -- i.e., are neither holidays nor weekend days. The
1208 /// behavior is undefined unless `beginDate` and `endDate` are within
1209 /// the valid range of this calendar, and `beginDate <= endDate`.
1210 int numBusinessDays(const Date& beginDate, const Date& endDate) const;
1211
1212 /// Return the number of (unique) holiday codes associated with the
1213 /// specified `date` in this calendar if `date` is a holiday in this
1214 /// calendar, and 0 otherwise. The behavior is undefined unless `date`
1215 /// is within the valid range of this calendar.
1216 int numHolidayCodes(const Date& date) const;
1217
1218 /// Return the total number of holiday codes for all holidays in this
1219 /// calendar. Note that this function is used primarily in conjunction
1220 /// with `reserveHolidayCodeCapacity`.
1221 int numHolidayCodesTotal() const;
1222
1223 /// Return the number of days in the valid range of this calendar that
1224 /// are individually marked as holidays, irrespective of whether or not
1225 /// the date is also considered a weekend day.
1226 int numHolidays() const;
1227
1228 /// Return the number of days in the valid range of this calendar that
1229 /// are *not* considered business days -- i.e., are either holidays,
1230 /// weekend days, or both. Note that
1231 /// `numNonBusinessDays() == length() - numBusinessDays()`.
1233
1234 /// Return the number of days in the valid range of this calendar that
1235 /// are considered weekend days, irrespective of any designated
1236 /// holidays.
1238
1239 /// Return the number of weekend-days transitions maintained by this
1240 /// calendar.
1241 int numWeekendDaysTransitions() const;
1242
1243 /// Return an iterator providing non-modifiable access to the last
1244 /// business day in this calendar. If this calendar has no valid
1245 /// business days, the returned iterator has the same value as that
1246 /// returned by `rendBusinessDays()`.
1248
1249 /// Return an iterator providing non-modifiable access to the first
1250 /// business day that occurs on or before the specified `date` in this
1251 /// calendar. If this calendar has no such business day, the returned
1252 /// iterator has the same value as that returned by
1253 /// `rendBusinessDays(date)`. The behavior is undefined unless `date`
1254 /// is within the valid range of this calendar.
1256
1257 /// Return an iterator providing non-modifiable access to the last
1258 /// holiday code associated with the specified `date` in this calendar.
1259 /// If there are no holiday codes associated with `date`, the returned
1260 /// iterator has the same value as that returned by
1261 /// `rendHolidayCodes(date)`. The behavior is undefined unless `date`
1262 /// is marked as a holiday in this calendar.
1264
1265 /// Return an iterator providing non-modifiable access to the last
1266 /// holiday code associated with the holiday referenced by the specified
1267 /// `iter`. If there are no holiday codes associated with the date
1268 /// referenced by `iter`, the returned iterator has the same value as
1269 /// that returned by `rendHolidayCodes(iter)`. The behavior is
1270 /// undefined unless `iter` refers to a valid holiday of this calendar.
1272 rbeginHolidayCodes(const HolidayConstIterator& iter) const;
1273
1274 /// Return an iterator providing non-modifiable access to the last
1275 /// holiday in this calendar. If this calendar has no holidays, the
1276 /// returned iterator has the same value as that returned by
1277 /// `rendHolidays()`.
1279
1280 /// Return an iterator providing non-modifiable access to the first
1281 /// holiday that occurs on or before the specified `date` in this
1282 /// calendar. If this calendar has no such holiday, the returned
1283 /// iterator has the same value as that returned by
1284 /// `rendHolidays(date)`. The behavior is undefined unless `date` is
1285 /// within the valid range of this calendar.
1287
1288 /// Return an iterator providing non-modifiable access to the last
1289 /// weekend-days transition in the chronological sequence of
1290 /// weekend-days transitions maintained by this calendar. If this
1291 /// calendar has no weekend-days transitions, the returned iterator has
1292 /// the same value as that returned by `rendWeekendDaysTransitions()`.
1295
1296 /// Return an iterator providing non-modifiable access to the element
1297 /// one before the first business day in this calendar.
1299
1300 /// Return an iterator providing non-modifiable access to the first
1301 /// business day that occurs before the specified `date` in this
1302 /// calendar. If this calendar has no such business day, the returned
1303 /// iterator has the same value as that returned by
1304 /// `rendBusinessDays()`. The behavior is undefined unless `date` is
1305 /// within the valid range of this calendar.
1307
1308 /// Return an iterator providing non-modifiable access to the element
1309 /// one before the first holiday code associated with the specified
1310 /// `date`. The behavior is undefined unless `date` is marked as a
1311 /// holiday in this calendar.
1313
1314 /// Return an iterator providing non-modifiable access to the element
1315 /// one before the first holiday code associated with the holiday
1316 /// referenced by the specified `iter`. The behavior is undefined
1317 /// unless `iter` references a valid holiday in this calendar.
1319 rendHolidayCodes(const HolidayConstIterator& iter) const;
1320
1321 /// Return an iterator providing non-modifiable access to the element
1322 /// one before the first holiday in this calendar.
1324
1325 /// Return an iterator providing non-modifiable access to the first
1326 /// holiday that occurs before the specified `date` in this calendar.
1327 /// If this calendar has no such holiday, the returned iterator has the
1328 /// same value as that returned by `rendHolidays()`. The behavior is
1329 /// undefined unless `date` is within the valid range of this calendar.
1331
1332 /// Return an iterator providing non-modifiable access to the element
1333 /// one before the first weekend-days transition in the chronological
1334 /// sequence of weekend-days transitions maintained by this calendar.
1337
1338 /// Return the weekend-days transition at the specified `index` in this
1339 /// calendar. For all `index` values from 0 to
1340 /// `numWeekendDaysTransitions() - 1` (inclusive), a unique weekend-days
1341 /// transition is returned. The mapping of `index` to weekend-days
1342 /// transition is invalidated when the set of weekend-days transitions
1343 /// is modified by an invocation of `addWeekendDay`, `addWeekendDays`,
1344 /// `addWeekendDaysTransition`, `intersectBusinessDays`,
1345 /// `intersectNonBusinessDays`, `removeAll`, `unionBusinessDays`, or
1346 /// `unionNonBusinessDays`. The behavior is undefined unless
1347 /// `0 <= index < numWeekendDaysTransitions()`.
1349
1350 // Aspects
1351
1352 /// Return the allocator used by this object to supply memory.
1353 bslma::Allocator *allocator() const;
1354
1355 /// Write this value to the specified output `stream` using the
1356 /// specified `version` format and return a reference to the modifiable
1357 /// `stream`. If `version` is not supported, `stream` is unmodified.
1358 /// Note that `version` is not written to `stream`. See the `bslx`
1359 /// package-level documentation for more information on BDEX streaming
1360 /// of value-semantic types and containers.
1361 template <class STREAM>
1362 STREAM& bdexStreamOut(STREAM& stream, int version) const;
1363
1364 /// Format this object to the specified output `stream` at the (absolute
1365 /// value of) the optionally specified indentation `level` and return a
1366 /// reference to the modifiable `stream`. If `level` is specified,
1367 /// optionally specify `spacesPerLevel`, the number of spaces per
1368 /// indentation level for this and all of its nested objects. If
1369 /// `level` is negative, suppress indentation of the first line. If
1370 /// `spacesPerLevel` is negative, format the entire output on one line,
1371 /// suppressing all but the initial indentation (as governed by
1372 /// `level`). If `stream` is not valid on entry, this operation has no
1373 /// effect.
1374 bsl::ostream& print(bsl::ostream& stream,
1375 int level = 0,
1376 int spacesPerLevel = 4) const;
1377
1378#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE2.22
1379
1380 // DEPRECATED METHODS
1381
1382 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
1383 ///
1384 /// Return the most current BDEX streaming version number supported by
1385 /// this class.
1386 static int maxSupportedBdexVersion();
1387
1388#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE2.22
1389};
1390
1391// FREE OPERATORS
1392
1393/// Return `true` if the specified `lhs` and `rhs` calendars have the same
1394/// value, and `false` otherwise. Two calendars have the same value if they
1395/// have the same valid range (or are both empty), the same weekend days,
1396/// the same holidays, and each corresponding pair of holidays has the same
1397/// (ordered) set of associated holiday codes.
1398bool operator==(const PackedCalendar& lhs, const PackedCalendar& rhs);
1399
1400/// Return `true` if the specified `lhs` and `rhs` calendars do not have the
1401/// same value, and `false` otherwise. Two calendars do not have the same
1402/// value if they do not have the same valid range (and are not both empty),
1403/// do not have the same weekend days, do not have the same holidays, or,
1404/// for at least one corresponding pair of holidays, do not have the same
1405/// (ordered) set of associated holiday codes.
1406bool operator!=(const PackedCalendar& lhs, const PackedCalendar& rhs);
1407
1408/// Write the value of the specified `calendar` to the specified output
1409/// `stream`, and return a reference to the modifiable `stream`.
1410bsl::ostream& operator<<(bsl::ostream& stream,
1411 const PackedCalendar& calendar);
1412
1413// FREE FUNCTIONS
1414
1415/// Pass the specified `object` to the specified `hashAlg`. This function
1416/// integrates with the `bslh` modular hashing system and effectively
1417/// provides a `bsl::hash` specialization for `PackedCalendar`.
1418template <class HASHALG>
1419void hashAppend(HASHALG& hashAlg, const PackedCalendar& object);
1420
1421/// Exchange the values of the specified `a` and `b` objects. This function
1422/// provides the no-throw exception-safety guarantee if the two objects were
1423/// created with the same allocator and the basic guarantee otherwise.
1425
1426 // ==============================
1427 // class PackedCalendar_DateProxy
1428 // ==============================
1429
1430/// This class serves as a proxy for `Date` for use by the arrow operator of
1431/// calendar iterators (e.g., `PackedCalendar_HolidayConstIterator`). An
1432/// object of this class behaves as the `Date` object with which it was
1433/// constructed.
1434///
1435/// See @ref bdlt_packedcalendar
1437
1438 // DATA
1439 Date d_date; // proxied date
1440
1441 private:
1442 // NOT IMPLEMENTED
1444
1445 public:
1446 // CREATORS
1447
1448 /// Create a proxy object for the specified `date`.
1449 PackedCalendar_DateProxy(const Date& date); // IMPLICIT
1450
1451 /// Destroy this object.
1453
1454 /// Create a proxy object referencing the same `Date` value as the
1455 /// specified `original` proxy.
1457
1458 // ACCESSORS
1459
1460 /// Return the address providing non-modifiable access to the proxied
1461 /// date object.
1462 const Date *operator->() const;
1463};
1464
1465 // ============================
1466 // class PackedCalendar_DateRef
1467 // ============================
1468
1469/// This private class is used by the arrow operator of the holiday
1470/// iterator and business day iterator classes. The objects instantiated
1471/// from this class serve as references to `Date` objects.
1472///
1473/// See @ref bdlt_packedcalendar
1475
1476 private:
1477 // NOT IMPLEMENTED
1479
1480 public:
1481 // CREATORS
1482
1483 /// Create a date reference object using the specified `date`.
1484 explicit PackedCalendar_DateRef(const Date& date);
1485
1486 /// Create a date reference object having the value of the specified
1487 /// `original` object.
1489
1490 /// Destroy this object.
1492
1493 // ACCESSORS
1494
1495 /// Return a proxy object to this object's referenced date.
1497};
1498
1499 // =========================================
1500 // class PackedCalendar_HolidayConstIterator
1501 // =========================================
1502
1503/// Provide read-only, sequential access in increasing (chronological) order
1504/// to the holidays in a `PackedCalendar` object. This class owns an
1505/// iterator into the `bdlc::PackedIntArray` storing the holiday offsets of
1506/// the referenced `bdlt::PackedCalendar` and a date, `d_firstDate`, to
1507/// convert the offsets into dates corresponding to holidays.
1508///
1509/// See @ref bdlt_packedcalendar
1511
1512 // DATA
1513 bdlc::PackedIntArray<int>::const_iterator d_iterator; // array's iterator
1514
1515 Date d_firstDate; // offset date
1516
1517 // FRIENDS
1518 friend class PackedCalendar;
1523
1524 private:
1525 // PRIVATE TYPES
1527
1528 // PRIVATE CREATORS
1529
1530 /// Create a holiday iterator using the specified `iter` and
1531 /// `firstDate`.
1533 const Date firstDate);
1534
1535 public:
1536 // TYPES
1538 typedef int difference_type;
1540
1541 /// The star operator returns a `PackedCalendar_DateRef` *by* *value*.
1543
1544#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE3.0
1545
1546 typedef bsl::bidirectional_iterator_tag iterator_category;
1547
1548#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE3.0
1549
1550
1551 // CREATORS
1552
1553 /// Create an iterator having the value of the specified `original`
1554 /// iterator.
1556 const PackedCalendar_HolidayConstIterator& original);
1557
1558 /// Destroy this object.
1560
1561 // MANIPULATORS
1562
1563 /// Assign to this iterator the value of the specified `rhs` iterator,
1564 /// and return a reference providing modifiable access to this object.
1567
1568 /// Advance this iterator to refer to the next holiday in the calendar,
1569 /// and return a reference providing modifiable access to this object.
1570 /// The behavior is undefined unless, on entry, this iterator
1571 /// references a valid holiday.
1573
1574 /// Regress this iterator to refer to the previous holiday in the
1575 /// calendar, and return a reference providing modifiable access to this
1576 /// object. The behavior is undefined unless, on entry, this iterator
1577 /// references a valid holiday that is not the first holiday in the
1578 /// associated calendar.
1580
1581 // ACCESSORS
1582
1583 /// Return a `PackedCalendar_DateRef` object that contains the date
1584 /// value of the holiday referenced by this iterator.
1586
1587 /// Return a date proxy for the holiday referenced by this iterator.
1589};
1590
1591// FREE OPERATORS
1592
1593/// Return `true` if the specified `lhs` and `rhs` iterators refer to the
1594/// same element in the same calendar, and `false` otherwise. The behavior
1595/// is undefined unless `lhs` and `rhs` both iterate over the same calendar.
1596bool operator==(const PackedCalendar_HolidayConstIterator& lhs,
1598
1599/// Return `true` if the specified `lhs` and `rhs` iterators do not refer to
1600/// the same element in the same calendar, and `false` otherwise. The
1601/// behavior is undefined unless `lhs` and `rhs` both iterate over the same
1602/// calendar.
1603bool operator!=(const PackedCalendar_HolidayConstIterator& lhs,
1605
1606/// Advance the specified `iterator` to refer to the next holiday in the
1607/// associated calendar, and return the previous value of `iterator`. The
1608/// behavior is undefined unless, on entry, `iterator` references a valid
1609/// holiday.
1612
1613/// Regress the specified `iterator` to refer to the previous holiday in the
1614/// associated calendar, and return the previous value of `iterator`. The
1615/// behavior is undefined unless, on entry, `iterator` references a valid
1616/// holiday that is not the first holiday in the associated calendar.
1619
1620 // =============================================
1621 // class PackedCalendar_HolidayCodeConstIterator
1622 // =============================================
1623
1624/// Provide read-only, sequential access in increasing (numerical) order to
1625/// the holiday codes in a `PackedCalendar` object.
1626///
1627/// See @ref bdlt_packedcalendar
1629
1630 // DATA
1631 bdlc::PackedIntArray<int>::const_iterator d_iterator; // array's iterator
1632
1633 // FRIENDS
1634 friend class PackedCalendar;
1639 friend bsl::ptrdiff_t operator-(
1642
1643 private:
1644 // PRIVATE TYPES
1646
1647 // PRIVATE CREATORS
1648
1649 /// Create a holiday-code iterator referencing the holiday code
1650 /// referred to by the specified `iter`.
1652 // IMPLICIT
1653
1654 public:
1655 // TYPES
1656 typedef int value_type;
1657 typedef int difference_type;
1658 typedef int *pointer;
1659
1660 /// The star operator returns an `int` *by* *value*.
1661 typedef int reference;
1662
1663#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE3.0
1664
1665 typedef bsl::bidirectional_iterator_tag iterator_category;
1666
1667#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE3.0
1668
1669 // CREATORS
1670
1671 /// Create an object having the value of the specified `original`
1672 /// iterator.
1675
1676 /// Destroy this object.
1678
1679 // MANIPULATORS
1680
1681 /// Assign to this object the value of the specified `rhs` iterator, and
1682 /// return a reference providing modifiable access to this object.
1685
1686 /// Advance this iterator to refer to the next holiday code for the
1687 /// associated date in the associated calendar, and return a reference
1688 /// providing modifiable access to this object. The behavior is
1689 /// undefined unless, on entry, this iterator references a valid
1690 /// holiday code.
1692
1693 /// Regress this iterator to refer to the previous holiday code for the
1694 /// associated date in the associated calendar, and return a reference
1695 /// providing modifiable access to this object. The behavior is
1696 /// undefined unless, on entry, this iterator references a valid
1697 /// holiday code that is not the first holiday code for the associated
1698 /// date in the calendar.
1700
1701 // ACCESSORS
1702
1703 /// Return the holiday code referenced by this iterator.
1704 int operator*() const;
1705};
1706
1707// FREE OPERATORS
1708
1709/// Return `true` if the specified `lhs` and `rhs` iterators refers to the
1710/// same element, and `false` otherwise. The behavior is undefined unless
1711/// `lhs` and `rhs` both reference the same holiday in the same calendar.
1714
1715/// Return `true` if the specified `lhs` and `rhs` iterators do not refer to
1716/// the same element, and `false` otherwise. The behavior is undefined
1717/// unless `lhs` and `rhs` both reference the same holiday in the same
1718/// calendar.
1721
1722/// Advance the specified `iterator` to refer to the next holiday code for
1723/// the associated date in the associated calendar, and return the previous
1724/// value of `iterator`. The behavior is undefined unless, on entry,
1725/// `iterator` references a valid holiday code.
1728
1729/// Regress the specified `iterator` to refer to the previous holiday code
1730/// for the associated date in the associated calendar, and return the
1731/// previous value of `iterator`. The behavior is undefined unless, on
1732/// entry, `iterator` references a valid holiday code that is not the first
1733/// holiday code for the associated date in the calendar.
1736
1737/// Return the number of elements between specified `lhs` and `rhs`. The
1738/// behavior is undefined unless `lhs` and `rhs` refer to codes associated
1739/// with the same holiday in the same calendar.
1742
1743 // =============================================
1744 // class PackedCalendar_BusinessDayConstIterator
1745 // =============================================
1746
1747/// Provide read-only, sequential access in increasing (chronological) order
1748/// to the business days in a `PackedCalendar` object.
1749///
1750/// See @ref bdlt_packedcalendar
1752
1753 // DATA
1755 // iterator for the holiday offsets
1756
1757 const PackedCalendar *d_calendar_p;
1758 // pointer to the calendar
1759
1760 int d_currentOffset;
1761 // offset of the date referenced by this iterator from
1762 // 'd_calendar_p->firstDate()'; if
1763 // 'd_endFlag && 0 < d_calendar_p->length()', must equal
1764 // 'd_calendar_p->lastDate() - d_calendar_p->firstDate()';
1765 // if 'd_endFlag && 0 == d_calendar_p->length()', must
1766 // equal 0
1767
1768 bool d_endFlag;
1769 // indicates an 'end' iterator if set to 'true'
1770
1771 // FRIENDS
1772 friend class PackedCalendar;
1777
1778 private:
1779 // PRIVATE TYPES
1781
1782 // PRIVATE CREATORS
1783
1784 /// Create a business day iterator for the specified `calendar`. If the
1785 /// specified `endIterFlag` is `false`, then this iterator references
1786 /// the first business day on or after the specified `startDate`;
1787 /// otherwise, this iterator references one business day *past* the
1788 /// first business day on or after `startDate`. If no business day
1789 /// matching the above specification exists, then this iterator will
1790 /// reference one day past the end of its range.
1792 const Date& startDate,
1793 bool endIterFlag);
1794
1795 // PRIVATE MANIPULATORS
1796
1797 /// Advance this iterator to the next business day. The behavior is
1798 /// undefined unless `false == d_endFlag`.
1799 void nextBusinessDay();
1800
1801 /// Regress this iterator to the previous business day. The behavior is
1802 /// undefined unless `*this != d_calendar_p->beginBusinessDays()`.
1803 void previousBusinessDay();
1804
1805 public:
1806 // TYPES
1808 typedef int difference_type;
1810
1811 /// The star operator returns a `PackedCalendar_DateRef` *by* *value*.
1813
1814#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE3.0
1815
1816 typedef bsl::bidirectional_iterator_tag iterator_category;
1817
1818#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE3.0
1819
1820 // CREATORS
1821
1822 /// Create an iterator having the value of the specified `original`
1823 /// iterator.
1826
1827 /// Destroy this object.
1829
1830 // MANIPULATORS
1831
1832 /// Assign to this iterator the value of the specified `rhs` iterator,
1833 /// and return a reference providing modifiable access to this object.
1836
1837 /// Advance this iterator to refer to the next business day in the
1838 /// associated calendar, and return a reference providing modifiable
1839 /// access to this object. The behavior is undefined unless, on entry,
1840 /// this iterator references a valid business day.
1842
1843 /// Regress this iterator to refer to the previous business day in the
1844 /// associated calendar, and return a reference providing modifiable
1845 /// access to this object. The behavior is undefined unless, on entry,
1846 /// this iterator references a valid business day that is not the first
1847 /// business day for the associated calendar.
1849
1850 // ACCESSORS
1851
1852 /// Return a `PackedCalendar_DateRef` object that contains the date
1853 /// value of the business day referenced by this iterator.
1855
1856 /// Return a date proxy for the business day referenced by this
1857 /// iterator.
1859};
1860
1861// FREE OPERATORS
1862
1863/// Return `true` if the specified `lhs` and `rhs` iterators refer to the
1864/// same element in the same calendar, and `false` otherwise. The behavior
1865/// is undefined unless `lhs` and `rhs` both iterate over the same calendar.
1868
1869/// Return `true` if the specified `lhs` and `rhs` iterators do not refer to
1870/// the same element in the same calendar, and `false` otherwise. The
1871/// behavior is undefined unless `lhs` and `rhs` both iterate over the same
1872/// calendar.
1875
1876/// Advance the specified `iterator` to refer to the next business day in
1877/// the associated calendar, and return the previous value of `iterator`.
1878/// The behavior is undefined unless, on entry, `iterator` references a
1879/// valid business day.
1882
1883/// Regress the specified `iterator` to refer to the previous business day
1884/// in the associated calendar, and return the previous value of `iterator`.
1885/// The behavior is undefined unless, on entry, `iterator` references a
1886/// valid business day that is not the first business day for the associated
1887/// calendar.
1890
1891// ============================================================================
1892// INLINE DEFINITIONS
1893// ============================================================================
1894
1895 // ------------------------------
1896 // class PackedCalendar_DateProxy
1897 // ------------------------------
1898
1899// CREATORS
1900inline
1902: d_date(date)
1903{
1904}
1905
1906inline
1910
1911inline
1913 const PackedCalendar_DateProxy& original)
1914: d_date(original.d_date)
1915{
1916}
1917
1918// ACCESSORS
1919inline
1921{
1922 return &d_date;
1923}
1924
1925 // ----------------------------
1926 // class PackedCalendar_DateRef
1927 // ----------------------------
1928
1929// CREATORS
1930inline
1932: Date(date)
1933{
1934}
1935
1936inline
1938 const PackedCalendar_DateRef& original)
1939: Date(original)
1940{
1941}
1942
1943inline
1947
1948// ACCESSORS
1949inline
1954
1955 // -----------------------------------------
1956 // class PackedCalendar_HolidayConstIterator
1957 // -----------------------------------------
1958
1959// PRIVATE CREATORS
1960inline
1961PackedCalendar_HolidayConstIterator::
1962 PackedCalendar_HolidayConstIterator(const OffsetsConstIterator& iter,
1963 const Date firstDate)
1964: d_iterator(iter)
1965, d_firstDate(firstDate)
1966{
1967}
1968
1969// CREATORS
1970inline
1971PackedCalendar_HolidayConstIterator::PackedCalendar_HolidayConstIterator(
1973: d_iterator(original.d_iterator)
1974, d_firstDate(original.d_firstDate)
1975{
1976}
1977
1978inline
1982
1983// MANIPULATORS
1984inline
1987{
1988 d_iterator = rhs.d_iterator;
1989 d_firstDate = rhs.d_firstDate;
1990 return *this;
1991}
1992
1993inline
1996{
1997 ++d_iterator;
1998 return *this;
1999}
2000
2001inline
2004{
2005 --d_iterator;
2006 return *this;
2007}
2008
2009// ACCESSORS
2010inline
2015
2016inline
2019{
2020 return PackedCalendar_DateProxy(this->operator*());
2021}
2022
2023} // close package namespace
2024
2025// FREE OPERATORS
2026inline
2027bool bdlt::operator==(const PackedCalendar_HolidayConstIterator& lhs,
2028 const PackedCalendar_HolidayConstIterator& rhs)
2029{
2030 return lhs.d_iterator == rhs.d_iterator;
2031}
2032
2033inline
2034bool bdlt::operator!=(const PackedCalendar_HolidayConstIterator& lhs,
2035 const PackedCalendar_HolidayConstIterator& rhs)
2036{
2037 return lhs.d_iterator != rhs.d_iterator;
2038}
2039
2040inline
2042 bdlt::operator++(PackedCalendar_HolidayConstIterator& iterator, int)
2043{
2044 PackedCalendar_HolidayConstIterator tmp(iterator);
2045 ++iterator;
2046 return tmp;
2047}
2048
2049inline
2051 bdlt::operator--(PackedCalendar_HolidayConstIterator& iterator, int)
2052{
2053 PackedCalendar_HolidayConstIterator tmp(iterator);
2054 --iterator;
2055 return tmp;
2056}
2057
2058namespace bdlt {
2059
2060 // ---------------------------------------------
2061 // class PackedCalendar_HolidayCodeConstIterator
2062 // ---------------------------------------------
2063
2064// PRIVATE CREATORS
2065inline
2066PackedCalendar_HolidayCodeConstIterator::
2067 PackedCalendar_HolidayCodeConstIterator(const CodesConstIterator& iter)
2068: d_iterator(iter)
2069{
2070}
2071
2072// CREATORS
2073inline
2074PackedCalendar_HolidayCodeConstIterator::
2075PackedCalendar_HolidayCodeConstIterator(
2077: d_iterator(original.d_iterator)
2078{
2079}
2080
2081inline
2086
2087// MANIPULATORS
2088inline
2092{
2093 d_iterator = rhs.d_iterator;
2094 return *this;
2095}
2096
2097inline
2100{
2101 ++d_iterator;
2102 return *this;
2103}
2104
2105inline
2108{
2109 --d_iterator;
2110 return *this;
2111}
2112
2113// ACCESSORS
2114inline
2116{
2117 return *d_iterator;
2118}
2119
2120} // close package namespace
2121
2122// FREE OPERATORS
2123inline
2124bool bdlt::operator==(const PackedCalendar_HolidayCodeConstIterator& lhs,
2125 const PackedCalendar_HolidayCodeConstIterator& rhs)
2126{
2127 return lhs.d_iterator == rhs.d_iterator;
2128}
2129
2130inline
2131bool bdlt::operator!=(const PackedCalendar_HolidayCodeConstIterator& lhs,
2132 const PackedCalendar_HolidayCodeConstIterator& rhs)
2133{
2134 return lhs.d_iterator != rhs.d_iterator;
2135}
2136
2137inline
2139 bdlt::operator++(PackedCalendar_HolidayCodeConstIterator& iterator, int)
2140{
2142 ++iterator;
2143 return tmp;
2144}
2145
2146inline
2148 bdlt::operator--(PackedCalendar_HolidayCodeConstIterator& iterator, int)
2149{
2150 PackedCalendar_HolidayCodeConstIterator tmp(iterator);
2151 --iterator;
2152 return tmp;
2153}
2154
2155inline
2156bsl::ptrdiff_t
2157 bdlt::operator-(const PackedCalendar_HolidayCodeConstIterator& lhs,
2158 const PackedCalendar_HolidayCodeConstIterator& rhs)
2159{
2160 return lhs.d_iterator - rhs.d_iterator;
2161}
2162
2163namespace bdlt {
2164
2165 // ---------------------------------------------
2166 // class PackedCalendar_BusinessDayConstIterator
2167 // ---------------------------------------------
2168
2169// CREATORS
2170inline
2171PackedCalendar_BusinessDayConstIterator::
2172PackedCalendar_BusinessDayConstIterator(
2174: d_offsetIter(original.d_offsetIter)
2175, d_calendar_p(original.d_calendar_p)
2176, d_currentOffset(original.d_currentOffset)
2177, d_endFlag(original.d_endFlag)
2178{
2179}
2180
2181inline
2186
2187// MANIPULATORS
2188inline
2191{
2192 BSLS_ASSERT_SAFE(false == d_endFlag);
2193
2194 nextBusinessDay();
2195 return *this;
2196}
2197
2198inline
2201{
2202 BSLS_ASSERT_SAFE(*this != d_calendar_p->beginBusinessDays());
2203
2204 previousBusinessDay();
2205 return *this;
2206}
2207
2208// ACCESSORS
2209inline
2212{
2213 return PackedCalendar_DateRef(d_calendar_p->firstDate() + d_currentOffset);
2214}
2215
2216inline
2219{
2220 return PackedCalendar_DateProxy(this->operator*());
2221}
2222
2223} // close package namespace
2224
2225// FREE OPERATORS
2226inline
2227bool bdlt::operator==(const PackedCalendar_BusinessDayConstIterator& lhs,
2228 const PackedCalendar_BusinessDayConstIterator& rhs)
2229{
2230 BSLS_ASSERT_SAFE(lhs.d_calendar_p == rhs.d_calendar_p);
2231
2232 return lhs.d_endFlag == rhs.d_endFlag
2233 && lhs.d_currentOffset == rhs.d_currentOffset;
2234}
2235
2236inline
2237bool bdlt::operator!=(const PackedCalendar_BusinessDayConstIterator& lhs,
2238 const PackedCalendar_BusinessDayConstIterator& rhs)
2239{
2240 BSLS_ASSERT_SAFE(lhs.d_calendar_p == rhs.d_calendar_p);
2241
2242 return lhs.d_endFlag != rhs.d_endFlag
2243 || lhs.d_currentOffset != rhs.d_currentOffset;
2244}
2245
2246inline
2248 PackedCalendar_BusinessDayConstIterator& iterator, int)
2249{
2250 PackedCalendar_BusinessDayConstIterator tmp(iterator);
2251 ++iterator;
2252 return tmp;
2253}
2254
2255inline
2257 PackedCalendar_BusinessDayConstIterator& iterator, int)
2258{
2259 PackedCalendar_BusinessDayConstIterator tmp(iterator);
2260 --iterator;
2261 return tmp;
2262}
2263
2264namespace bdlt {
2265
2266 // --------------------
2267 // class PackedCalendar
2268 // --------------------
2269
2270// PRIVATE ACCESSORS
2271inline
2272PackedCalendar::CodesConstIterator
2273 PackedCalendar::beginHolidayCodes(const OffsetsConstIterator& iter) const
2274{
2275 BSLS_ASSERT_SAFE(isHoliday(d_firstDate + *iter));
2276
2277 const int indexOffset = static_cast<int>(iter - d_holidayOffsets.begin());
2278
2279 const bsl::size_t codeOffset = d_holidayCodesIndex[indexOffset];
2280
2281 return d_holidayCodes.begin() + codeOffset;
2282}
2283
2284inline
2285PackedCalendar::CodesConstIterator
2286 PackedCalendar::endHolidayCodes(const OffsetsConstIterator& iter) const
2287{
2288 BSLS_ASSERT_SAFE(isHoliday(d_firstDate + *iter));
2289
2290 const bsl::size_t endIndexOffset = iter - d_holidayOffsets.begin() + 1;
2291
2292 const bsl::size_t iterIndex = endIndexOffset ==
2293 d_holidayCodesIndex.length()
2294 ? d_holidayCodes.length()
2295 : d_holidayCodesIndex[endIndexOffset];
2296 return d_holidayCodes.begin() + iterIndex;
2297}
2298
2299// CLASS METHODS
2300
2301 // Aspects
2302
2303inline
2305{
2306 if (versionSelector >= 20150612) {
2307 return 3; // RETURN
2308 }
2309 return 2;
2310}
2311
2312// MANIPULATORS
2313inline
2314int PackedCalendar::addHolidayCodeIfInRange(const Date& date, int holidayCode)
2315{
2316 if (isInRange(date)) {
2318 return 0; // RETURN
2319 }
2320 return -1;
2321}
2322
2323inline
2325{
2326 if (isInRange(date)) {
2327 addHoliday(date);
2328 return 0; // RETURN
2329 }
2330 return -1;
2331}
2332
2333inline
2335{
2337
2338 d_holidayOffsets.reserveCapacity(numHolidays);
2339 d_holidayCodesIndex.reserveCapacity(numHolidays);
2340}
2341
2342inline
2344{
2346
2347 d_holidayCodes.reserveCapacity(numHolidayCodes);
2348}
2349
2350 // Aspects
2351
2352template <class STREAM>
2353STREAM& PackedCalendar::bdexStreamIn(STREAM& stream, int version)
2354{
2355 if (stream) {
2356 switch (version) { // Switch on the schema version (starting with 1).
2357 case 3: {
2359 firstDate.bdexStreamIn(stream, 1);
2360
2361 if (!stream) {
2362 return stream; // RETURN
2363 }
2364
2366 lastDate.bdexStreamIn(stream, 1);
2367
2368 if (!stream
2369 || (firstDate > lastDate
2370 && (firstDate != Date(9999,12,31)
2371 || lastDate != Date(1,1,1)))) {
2372 stream.invalidate();
2373 return stream; // RETURN
2374 }
2375
2376 int length = lastDate - firstDate + 1;
2377
2378 int transitionsLength = 0;
2379 stream.getLength(transitionsLength);
2380
2381 if (!stream || transitionsLength < 0) {
2382 stream.invalidate();
2383 return stream; // RETURN
2384 }
2385
2387 weekendDaysTransitions(transitionsLength, d_allocator_p);
2388 for (int i = 0; i < transitionsLength; ++i) {
2389 WeekendDaysTransition& wdt = weekendDaysTransitions[i];
2390
2391 wdt.first.bdexStreamIn(stream, 1);
2392
2393 if (!stream) {
2394 return stream; // RETURN
2395 }
2396
2397 // The data must be monotonically increasing.
2398
2399 if (i && wdt.first <= weekendDaysTransitions[i - 1].first) {
2400 stream.invalidate();
2401 return stream; // RETURN
2402 }
2403
2404 wdt.second.bdexStreamIn(stream, 1);
2405
2406 if (!stream) {
2407 return stream; // RETURN
2408 }
2409 }
2410
2411 bdlc::PackedIntArray<int> holidayOffsets(d_allocator_p);
2412 holidayOffsets.bdexStreamIn(stream, 1);
2413
2414 if (!stream
2415 || (firstDate > lastDate && !holidayOffsets.isEmpty())
2416 || (firstDate <= lastDate
2417 && (static_cast<int>(holidayOffsets.length()) > length
2418 || (!holidayOffsets.isEmpty()
2419 && (holidayOffsets[0] < 0
2420 || holidayOffsets[0] > length))))) {
2421 stream.invalidate();
2422 return stream; // RETURN
2423 }
2424
2425 // The values in 'holidayOffsets' must be monotonically increasing
2426 // and represent dates within the valid range.
2427
2428 for (bsl::size_t i = 1; i < holidayOffsets.length(); ++i) {
2429 if (holidayOffsets[i - 1] >= holidayOffsets[i]
2430 || holidayOffsets[i] > length) {
2431 stream.invalidate();
2432 return stream; // RETURN
2433 }
2434 }
2435
2436 bdlc::PackedIntArray<int> holidayCodesIndex(d_allocator_p);
2437 holidayCodesIndex.bdexStreamIn(stream, 1);
2438
2439 if (!stream
2440 || holidayCodesIndex.length() != holidayOffsets.length()
2441 || (!holidayCodesIndex.isEmpty() && holidayCodesIndex[0] != 0)) {
2442 stream.invalidate();
2443 return stream; // RETURN
2444 }
2445
2446 // The values in 'holidayCodesIndex' must be monotonically
2447 // non-decreasing.
2448
2449 for (bsl::size_t i = 1; i < holidayCodesIndex.length(); ++i) {
2450 if (holidayCodesIndex[i - 1] > holidayCodesIndex[i]) {
2451 stream.invalidate();
2452 return stream; // RETURN
2453 }
2454 }
2455
2456 bdlc::PackedIntArray<int> holidayCodes(d_allocator_p);
2457 holidayCodes.bdexStreamIn(stream, 1);
2458
2459 if (!stream
2460 || (holidayOffsets.isEmpty() && !holidayCodes.isEmpty())) {
2461 stream.invalidate();
2462 return stream; // RETURN
2463 }
2464
2465 // The values in the segments of 'holidayOffsets' must be
2466 // monotonically increasing.
2467
2468 bsl::size_t index = 0;
2469 for (int i = 0; i < static_cast<int>(holidayCodes.length()); ++i) {
2470 if (index < holidayCodesIndex.length()
2471 && i == holidayCodesIndex[index]) {
2472 ++index;
2473 while (index < holidayCodesIndex.length()
2474 && i == holidayCodesIndex[index]) {
2475 ++index;
2476 }
2477 }
2478 else if (holidayCodes[i - 1] >= holidayCodes[i]) {
2479 stream.invalidate();
2480 return stream; // RETURN
2481 }
2482 }
2483
2484 bslalg::SwapUtil::swap(&d_firstDate, &firstDate);
2485 bslalg::SwapUtil::swap(&d_lastDate, &lastDate);
2486 bslalg::SwapUtil::swap(&d_weekendDaysTransitions,
2487 &weekendDaysTransitions);
2488 bslalg::SwapUtil::swap(&d_holidayOffsets, &holidayOffsets);
2489 bslalg::SwapUtil::swap(&d_holidayCodesIndex, &holidayCodesIndex);
2490 bslalg::SwapUtil::swap(&d_holidayCodes, &holidayCodes);
2491 } break;
2492 case 2: {
2493 PackedCalendar inCal(d_allocator_p);
2494 inCal.d_firstDate.bdexStreamIn(stream, 1);
2495 if (!stream) {
2496 return stream; // RETURN
2497 }
2498
2499 inCal.d_lastDate.bdexStreamIn(stream, 1);
2500 if (!stream
2501 || (inCal.d_firstDate > inCal.d_lastDate
2502 && (inCal.d_firstDate != Date(9999,12,31)
2503 || inCal.d_lastDate != Date(1,1,1)))) {
2504 stream.invalidate();
2505 return stream; // RETURN
2506 }
2507 int length = inCal.d_lastDate - inCal.d_firstDate + 1;
2508
2509 int transitionsLength = 0;
2510 stream.getLength(transitionsLength);
2511 if (!stream || transitionsLength < 0)
2512 {
2513 stream.invalidate();
2514 return stream; // RETURN
2515 }
2516
2517 int offsetsLength = 0;
2518 stream.getLength(offsetsLength);
2519 if (!stream
2520 || (inCal.d_firstDate > inCal.d_lastDate
2521 && offsetsLength != 0)
2522 || (inCal.d_firstDate <= inCal.d_lastDate
2523 && (offsetsLength < 0 || offsetsLength > length))) {
2524 stream.invalidate();
2525 return stream; // RETURN
2526 }
2527 BSLS_ASSERT(offsetsLength >= 0);
2528
2529 int codesLength = 0;
2530 stream.getLength(codesLength);
2531 if (!stream || (0 == offsetsLength && codesLength != 0)) {
2532 stream.invalidate();
2533 return stream; // RETURN
2534 }
2535
2536 inCal.d_weekendDaysTransitions.resize(transitionsLength);
2537
2538 // To ensure 'inCal' cannot be in an invalid state, we must first
2539 // reserve capacity for the three 'PackedIntArray' and then resize
2540 // them to guarantee the operations can complete without
2541 // re-allocation *and* the object invariants (see the destructor
2542 // implementation) are maintained.
2543
2544 inCal.d_holidayOffsets.reserveCapacity(offsetsLength);
2545 inCal.d_holidayCodesIndex.reserveCapacity(offsetsLength);
2546 inCal.d_holidayCodes.reserveCapacity(codesLength);
2547
2548 inCal.d_holidayOffsets.resize(offsetsLength);
2549 inCal.d_holidayCodesIndex.resize(offsetsLength);
2550 inCal.d_holidayCodes.resize(codesLength);
2551
2553 inCal.d_weekendDaysTransitions.begin();
2554 it != inCal.d_weekendDaysTransitions.end();
2555 ++it) {
2556 it->first.bdexStreamIn(stream, 1);
2557 if (!stream) {
2558 return stream; // RETURN
2559 }
2560
2561 if (it != inCal.d_weekendDaysTransitions.begin()
2562 && it->first <= (it - 1)->first) {
2563 stream.invalidate();
2564 return stream; // RETURN
2565 }
2566
2567 it->second.bdexStreamIn(stream, 1);
2568 if (!stream) {
2569 return stream; // RETURN
2570 }
2571 }
2572
2573 int previousValue = -1;
2574 for (int i = 0; i < offsetsLength; ++i) {
2575 int tmp;
2576 stream.getInt32(tmp);
2577 if (!stream
2578 || tmp < 0
2579 || tmp >= length
2580 || tmp <= previousValue) {
2581 stream.invalidate();
2582 return stream; // RETURN
2583 }
2584 inCal.d_holidayOffsets.replace(i, tmp);
2585 previousValue = tmp;
2586 }
2587
2588 previousValue = -1;
2589 for (int i = 0; i < offsetsLength; ++i) {
2590 int tmp;
2591 stream.getInt32(tmp);
2592
2593 // This vector is ordered but duplicates are allowed. The
2594 // first element must be 0.
2595
2596 if (!stream
2597 || tmp < 0
2598 || tmp < previousValue
2599 || tmp > codesLength
2600 || (0 == i && 0 != tmp)) {
2601
2602 // If we get here, some of the code indices could
2603 // potentially be greater than 'codesLength'. That would
2604 // trigger an assertion in the destructor. So call
2605 // 'removeAll' to clean up.
2606
2607 inCal.removeAll();
2608 stream.invalidate();
2609 return stream; // RETURN
2610 }
2611 inCal.d_holidayCodesIndex.replace(i, tmp);
2612 previousValue = tmp;
2613 }
2614
2615 CodesIndexConstIterator it = inCal.d_holidayCodesIndex.begin();
2616 CodesIndexConstIterator end = inCal.d_holidayCodesIndex.end();
2617
2618 // Skip the holidays that have no codes.
2619
2620 while (it != end && 0 == *it) {
2621 ++it;
2622 }
2623
2624 // 'it' is now positioned at the first holiday with one or more
2625 // codes or at the end.
2626
2627 bool previousValueFlag = false; // This flag is used to determine
2628 // if we are inside an ordered
2629 // sequence of codes (i.e.,
2630 // 'previousValue' refers to a
2631 // code for the same holiday as
2632 // 'value').
2633
2634 for (int i = 0; i < codesLength; ++i) {
2635 int tmp;
2636 stream.getInt32(tmp);
2637 if (!stream
2638 || (previousValueFlag && tmp <= previousValue)) {
2639 stream.invalidate();
2640 return stream; // RETURN
2641 }
2642 inCal.d_holidayCodes.replace(i, tmp);
2643
2644 // Regardless of whether or not there is more data, advance the
2645 // index iterator as needed and update 'previousValueFlag' if
2646 // 'it' moves.
2647
2648 if (it != end && i == (*it - 1)) {
2649 previousValueFlag = false;
2650
2651 while (it != end && i == (*it - 1)) {
2652 ++it; // Skip the holidays that have no codes.
2653 }
2654 }
2655 else {
2656 previousValueFlag = true;
2657 }
2658 previousValue = tmp;
2659 }
2660 BSLS_ASSERT(it == end);
2661
2662 swap(inCal); // This cannot throw.
2663 } break;
2664 case 1: {
2665 PackedCalendar inCal(d_allocator_p);
2666 inCal.d_firstDate.bdexStreamIn(stream, 1);
2667 if (!stream) {
2668 return stream; // RETURN
2669 }
2670
2671 inCal.d_lastDate.bdexStreamIn(stream, 1);
2672 if (!stream
2673 || (inCal.d_firstDate > inCal.d_lastDate
2674 && (inCal.d_firstDate != Date(9999, 12, 31)
2675 || inCal.d_lastDate != Date(1, 1, 1)))) {
2676 stream.invalidate();
2677 return stream; // RETURN
2678 }
2679 int length = inCal.d_lastDate - inCal.d_firstDate + 1;
2680
2681 DayOfWeekSet weekendDays;
2682 weekendDays.bdexStreamIn(stream, 1);
2683 if (!stream) {
2684 return stream; // RETURN
2685 }
2686
2687 if (weekendDays.length() > 0) {
2688 inCal.addWeekendDays(weekendDays);
2689 }
2690
2691 int offsetsLength = 0;
2692 stream.getLength(offsetsLength);
2693 if (!stream
2694 || (inCal.d_firstDate > inCal.d_lastDate
2695 && offsetsLength != 0)
2696 || (inCal.d_firstDate <= inCal.d_lastDate
2697 && (offsetsLength < 0 || offsetsLength > length))) {
2698 stream.invalidate();
2699 return stream; // RETURN
2700 }
2701 BSLS_ASSERT(offsetsLength >= 0);
2702
2703 int codesLength = 0;
2704 stream.getLength(codesLength);
2705 if (!stream || (0 == offsetsLength && codesLength != 0)) {
2706 stream.invalidate();
2707 return stream; // RETURN
2708 }
2709
2710 // To ensure 'inCal' cannot be in an invalid state, we must first
2711 // reserve capacity for the three 'PackedIntArray' and then resize
2712 // them to guarantee the operations can complete without
2713 // re-allocation *and* the object invariants (see the destructor
2714 // implementation) are maintained.
2715
2716 inCal.d_holidayOffsets.reserveCapacity(offsetsLength);
2717 inCal.d_holidayCodesIndex.reserveCapacity(offsetsLength);
2718 inCal.d_holidayCodes.reserveCapacity(codesLength);
2719
2720 inCal.d_holidayOffsets.resize(offsetsLength);
2721 inCal.d_holidayCodesIndex.resize(offsetsLength);
2722 inCal.d_holidayCodes.resize(codesLength);
2723
2724 int previousValue = -1;
2725 for (int i = 0; i < offsetsLength; ++i) {
2726 int tmp;
2727 stream.getInt32(tmp);
2728 if (!stream
2729 || tmp < 0
2730 || tmp >= length
2731 || tmp <= previousValue) {
2732 stream.invalidate();
2733 return stream; // RETURN
2734 }
2735 inCal.d_holidayOffsets.replace(i, tmp);
2736 previousValue = tmp;
2737 }
2738
2739 previousValue = -1;
2740 for (int i = 0; i < offsetsLength; ++i) {
2741 int tmp;
2742 stream.getInt32(tmp);
2743
2744 // This vector is ordered but duplicates are allowed. The
2745 // first element must be 0.
2746
2747 if (!stream
2748 || tmp < 0
2749 || tmp < previousValue
2750 || tmp > codesLength
2751 || (0 == i && 0 != tmp)) {
2752
2753 // If we get here, some of the code indices could
2754 // potentially be greater than 'codesLength'. That would
2755 // trigger an assertion in the destructor. So call
2756 // 'removeAll' to clean up.
2757
2758 inCal.removeAll();
2759 stream.invalidate();
2760 return stream; // RETURN
2761 }
2762 inCal.d_holidayCodesIndex.replace(i, tmp);
2763 previousValue = tmp;
2764 }
2765
2766 CodesIndexConstIterator it = inCal.d_holidayCodesIndex.begin();
2767 CodesIndexConstIterator end = inCal.d_holidayCodesIndex.end();
2768
2769 // Skip the holidays that have no codes.
2770
2771 while (it != end && 0 == *it) {
2772 ++it;
2773 }
2774
2775 // 'it' is now positioned at the first holiday with one or more
2776 // codes or at the end.
2777
2778 bool previousValueFlag = false; // This flag is used to determine
2779 // if we are inside an ordered
2780 // sequence of codes (i.e.,
2781 // 'previousValue' refers to a
2782 // code for the same holiday as
2783 // 'value').
2784
2785 for (int i = 0; i < codesLength; ++i) {
2786 int tmp;
2787 stream.getInt32(tmp);
2788 if (!stream
2789 || (previousValueFlag && tmp <= previousValue)) {
2790 stream.invalidate();
2791 return stream; // RETURN
2792 }
2793 inCal.d_holidayCodes.replace(i, tmp);
2794
2795 // Regardless of whether or not there is more data, advance the
2796 // index iterator as needed and update 'previousValueFlag' if
2797 // 'it' moves.
2798
2799 if (it != end && i == (*it - 1)) {
2800 previousValueFlag = false;
2801
2802 while (it != end && i == (*it - 1)) {
2803 ++it; // Skip the holidays that have no codes.
2804 }
2805 }
2806 else {
2807 previousValueFlag = true;
2808 }
2809 previousValue = tmp;
2810 }
2811 BSLS_ASSERT(it == end);
2812
2813 swap(inCal); // This cannot throw.
2814 } break;
2815 default: {
2816 stream.invalidate();
2817 }
2818 }
2819 }
2820 return stream;
2821}
2822
2823// ACCESSORS
2824inline
2827{
2828 return BusinessDayConstIterator(*this, d_firstDate, false);
2829}
2830
2831inline
2834{
2836
2837 return BusinessDayConstIterator(*this, date, false);
2838}
2839
2840inline
2842 PackedCalendar::beginHolidayCodes(const HolidayConstIterator& iter) const
2843{
2845
2846 return HolidayCodeConstIterator(beginHolidayCodes(iter.d_iterator));
2847}
2848
2849inline
2851{
2852 return HolidayConstIterator(d_holidayOffsets.begin(), d_firstDate);
2853}
2854
2855inline
2858{
2860
2862 d_holidayOffsets.begin(),
2863 d_holidayOffsets.end(),
2864 date - d_firstDate);
2865 return HolidayConstIterator(i, d_firstDate);
2866}
2867
2868inline
2871{
2872 return d_weekendDaysTransitions.begin();
2873}
2874
2875inline
2878{
2879 return BusinessDayConstIterator(*this, d_lastDate, true);
2880}
2881
2882inline
2885{
2887
2888 return BusinessDayConstIterator(*this, date, true);
2889}
2890
2891inline
2893 PackedCalendar::endHolidayCodes(const HolidayConstIterator& iter) const
2894{
2896
2897 return endHolidayCodes(iter.d_iterator);
2898}
2899
2900inline
2902{
2903 return HolidayConstIterator(d_holidayOffsets.end(), d_firstDate);
2904}
2905
2906inline
2909{
2911
2913 d_holidayOffsets.begin(),
2914 d_holidayOffsets.end(),
2915 date - d_firstDate);
2916 return HolidayConstIterator(i, d_firstDate);
2917}
2918
2919inline
2922{
2923 return d_weekendDaysTransitions.end();
2924}
2925
2926inline
2928{
2929 BSLS_ASSERT_SAFE(d_firstDate <= d_lastDate);
2930
2931 return d_firstDate;
2932}
2933
2934inline
2936 const Date& date) const
2937{
2938 BSLS_ASSERT_SAFE(nextBusinessDay);
2939 BSLS_ASSERT_SAFE(Date(9999, 12, 31) > date);
2940 BSLS_ASSERT_SAFE(isInRange(date + 1));
2941
2942 enum { e_SUCCESS = 0, e_FAILURE = 1 };
2943
2945 if (iter == endBusinessDays()) {
2946 return e_FAILURE; // RETURN
2947 }
2948 *nextBusinessDay = *iter;
2949 return e_SUCCESS;
2950}
2951
2952inline
2954{
2955 BSLS_ASSERT_SAFE(0 <= index);
2956 BSLS_ASSERT_SAFE( index < numHolidays());
2957
2958 return d_firstDate + d_holidayOffsets[index];
2959}
2960
2961inline
2962int PackedCalendar::holidayCode(const Date& date, int index) const
2963{
2966 BSLS_ASSERT_SAFE(0 <= index);
2967 BSLS_ASSERT_SAFE( index < numHolidayCodes(date));
2968
2969 const int offset = date - d_firstDate;
2970 const OffsetsConstIterator offsetBegin = d_holidayOffsets.begin();
2971 const OffsetsConstIterator offsetEnd = d_holidayOffsets.end();
2973 offsetBegin,
2974 offsetEnd,
2975 offset);
2976 return d_holidayCodes[d_holidayCodesIndex[i - offsetBegin] + index];
2977}
2978
2979inline
2981{
2983
2984 return !isNonBusinessDay(date);
2985}
2986
2987inline
2988bool PackedCalendar::isHoliday(const Date& date) const
2989{
2991
2992 const int offset = date - d_firstDate;
2993 const OffsetsConstIterator offsetEnd = d_holidayOffsets.end();
2995 d_holidayOffsets.begin(),
2996 offsetEnd,
2997 offset);
2998
2999 return i != offsetEnd && *i == offset;
3000}
3001
3002inline
3003bool PackedCalendar::isInRange(const Date& date) const
3004{
3005 return d_firstDate <= date && date <= d_lastDate;
3006}
3007
3008inline
3010{
3012
3013 return isWeekendDay(date) || isHoliday(date);
3014}
3015
3016inline
3018{
3020 BSLS_ASSERT_SAFE(d_weekendDaysTransitions.size() <= 1);
3022
3023 if (d_weekendDaysTransitions.empty()) {
3024 return false; // RETURN
3025 }
3026
3027 BSLS_ASSERT_SAFE(d_weekendDaysTransitions[0].first == Date(1,1,1));
3028
3029 return d_weekendDaysTransitions[0].second.isMember(dayOfWeek);
3030}
3031
3032inline
3034{
3035 BSLS_ASSERT_SAFE(d_firstDate <= d_lastDate);
3036
3037 return d_lastDate;
3038}
3039
3040inline
3042{
3043 return d_firstDate <= d_lastDate ? d_lastDate - d_firstDate + 1 : 0;
3044}
3045
3046inline
3048{
3049 return length() - numNonBusinessDays();
3050}
3051
3052inline
3054{
3055 return static_cast<int>(d_holidayCodes.length());
3056}
3057
3058inline
3060{
3061 return static_cast<int>(d_holidayOffsets.length());
3062}
3063
3064inline
3066{
3067 return static_cast<int>(d_weekendDaysTransitions.size());
3068}
3069
3070inline
3076
3077inline
3080{
3082
3084}
3085
3086inline
3089{
3091
3092 return HolidayCodeConstReverseIterator(endHolidayCodes(date));
3093}
3094
3095inline
3098{
3100
3101 return HolidayCodeConstReverseIterator(endHolidayCodes(iter));
3102}
3103
3104inline
3110
3111inline
3114{
3116
3118}
3119
3120inline
3123{
3125 d_weekendDaysTransitions.end());
3126}
3127
3128inline
3134
3135inline
3138{
3140
3142}
3143
3144inline
3147{
3149
3150 return HolidayCodeConstReverseIterator(beginHolidayCodes(date));
3151}
3152
3153inline
3156{
3158
3159 return HolidayCodeConstReverseIterator(beginHolidayCodes(iter));
3160}
3161
3162inline
3168
3169inline
3172{
3174
3176}
3177
3178inline
3181{
3183 d_weekendDaysTransitions.begin());
3184}
3185
3186inline
3189{
3190 BSLS_ASSERT_SAFE(0 <= index);
3192
3193 return d_weekendDaysTransitions[index];
3194}
3195
3196 // Aspects
3197
3198inline
3200{
3201 return d_allocator_p;
3202}
3203
3204template <class STREAM>
3205STREAM& PackedCalendar::bdexStreamOut(STREAM& stream, int version) const
3206{
3207 switch (version) { // Switch on the schema version (starting with 1).
3208 case 3: {
3209 d_firstDate.bdexStreamOut(stream, 1);
3210 d_lastDate.bdexStreamOut(stream, 1);
3211
3212 stream.putLength(static_cast<int>(d_weekendDaysTransitions.size()));
3214 i < d_weekendDaysTransitions.size();
3215 ++i) {
3216 d_weekendDaysTransitions[i].first.bdexStreamOut(stream, 1);
3217 d_weekendDaysTransitions[i].second.bdexStreamOut(stream, 1);
3218 }
3219
3220 d_holidayOffsets.bdexStreamOut(stream, 1);
3221 d_holidayCodesIndex.bdexStreamOut(stream, 1);
3222 d_holidayCodes.bdexStreamOut(stream, 1);
3223 } break;
3224 case 2: {
3225 d_firstDate.bdexStreamOut(stream, 1);
3226 d_lastDate.bdexStreamOut(stream, 1);
3227
3228 stream.putLength(static_cast<int>(d_weekendDaysTransitions.size()));
3229 stream.putLength(static_cast<int>(d_holidayOffsets.length()));
3230 stream.putLength(static_cast<int>(d_holidayCodes.length()));
3231
3233 i < d_weekendDaysTransitions.size();
3234 ++i) {
3235 d_weekendDaysTransitions[i].first.bdexStreamOut(stream, 1);
3236 d_weekendDaysTransitions[i].second.bdexStreamOut(stream, 1);
3237 }
3238
3239 for (bsl::size_t i = 0; i < d_holidayOffsets.length(); ++i) {
3240 stream.putInt32(d_holidayOffsets[i]);
3241 }
3242 for (bsl::size_t i = 0; i < d_holidayCodesIndex.length(); ++i) {
3243 stream.putInt32(d_holidayCodesIndex[i]);
3244 }
3245 for (bsl::size_t i = 0; i < d_holidayCodes.length(); ++i) {
3246 stream.putInt32(d_holidayCodes[i]);
3247 }
3248 } break;
3249 case 1: {
3250 d_firstDate.bdexStreamOut(stream, 1);
3251 d_lastDate.bdexStreamOut(stream, 1);
3252
3253 if (!d_weekendDaysTransitions.empty() &&
3254 d_weekendDaysTransitions[0].first == Date(1, 1, 1)) {
3255 d_weekendDaysTransitions[0].second.bdexStreamOut(stream, 1);
3256 }
3257 else {
3258 DayOfWeekSet tempSet;
3259 tempSet.bdexStreamOut(stream, 1);
3260 }
3261
3262 stream.putLength(static_cast<int>(d_holidayOffsets.length()));
3263 stream.putLength(static_cast<int>(d_holidayCodes.length()));
3264
3265 for (bsl::size_t i = 0; i < d_holidayOffsets.length(); ++i) {
3266 stream.putInt32(d_holidayOffsets[i]);
3267 }
3268 for (bsl::size_t i = 0; i < d_holidayCodesIndex.length(); ++i) {
3269 stream.putInt32(d_holidayCodesIndex[i]);
3270 }
3271 for (bsl::size_t i = 0; i < d_holidayCodes.length(); ++i) {
3272 stream.putInt32(d_holidayCodes[i]);
3273 }
3274 } break;
3275 default: {
3276 stream.invalidate();
3277 }
3278
3279 }
3280 return stream;
3281}
3282
3283#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE2.22
3284
3285// DEPRECATED METHODS
3286inline
3288{
3289 return 1;
3290}
3291
3292#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE2.22
3293
3294} // close package namespace
3295
3296// FREE OPERATORS
3297inline
3298bool bdlt::operator!=(const PackedCalendar& lhs, const PackedCalendar& rhs)
3299{
3300 return !(lhs == rhs);
3301}
3302
3303// FREE FUNCTIONS
3304template <class HASHALG>
3305inline
3306void bdlt::hashAppend(HASHALG& hashAlg, const PackedCalendar& object)
3307{
3308 using ::BloombergLP::bslh::hashAppend;
3309 hashAppend(hashAlg, object.d_firstDate);
3310 hashAppend(hashAlg, object.d_lastDate);
3311 hashAppend(hashAlg, object.d_weekendDaysTransitions);
3312 hashAppend(hashAlg, object.d_holidayOffsets);
3313 hashAppend(hashAlg, object.d_holidayCodesIndex);
3314 hashAppend(hashAlg, object.d_holidayCodes);
3315}
3316
3317
3318
3319// TRAITS
3320
3321namespace bslma {
3322
3323template <>
3324struct UsesBslmaAllocator<bdlt::PackedCalendar> : bsl::true_type {};
3325
3326} // close namespace bslma
3327
3328
3329#endif
3330
3331// ----------------------------------------------------------------------------
3332// Copyright 2018 Bloomberg Finance L.P.
3333//
3334// Licensed under the Apache License, Version 2.0 (the "License");
3335// you may not use this file except in compliance with the License.
3336// You may obtain a copy of the License at
3337//
3338// http://www.apache.org/licenses/LICENSE-2.0
3339//
3340// Unless required by applicable law or agreed to in writing, software
3341// distributed under the License is distributed on an "AS IS" BASIS,
3342// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3343// See the License for the specific language governing permissions and
3344// limitations under the License.
3345// ----------------------------- END-OF-FILE ----------------------------------
3346
3347/** @} */
3348/** @} */
3349/** @} */
Definition bdlc_packedintarray.h:770
Definition bdlc_packedintarray.h:1048
const_iterator end() const
Definition bdlc_packedintarray.h:2556
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlc_packedintarray.h:2527
const_iterator begin() const
Definition bdlc_packedintarray.h:2535
bool isEmpty() const
Definition bdlc_packedintarray.h:2572
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlc_packedintarray.h:2316
void resize(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2484
bsl::size_t length() const
Return number of elements in this array.
Definition bdlc_packedintarray.h:2586
void reserveCapacity(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2451
void replace(bsl::size_t dstIndex, TYPE value)
Definition bdlc_packedintarray.h:2423
Definition bdlt_calendarreverseiteratoradapter.h:298
Definition bdlt_date.h:294
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_date.h:985
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_date.h:896
Definition bdlt_dayofweekset.h:398
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_dayofweekset.h:813
int length() const
Return the number of elements in this set.
Definition bdlt_dayofweekset.h:869
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_dayofweekset.h:889
Definition bdlt_packedcalendar.h:1751
PackedCalendar_DateProxy operator->() const
Definition bdlt_packedcalendar.h:2218
PackedCalendar_BusinessDayConstIterator & operator++()
Definition bdlt_packedcalendar.h:2190
int difference_type
Definition bdlt_packedcalendar.h:1808
PackedCalendar_DateProxy pointer
Definition bdlt_packedcalendar.h:1809
Date value_type
Definition bdlt_packedcalendar.h:1807
PackedCalendar_DateRef reference
The star operator returns a PackedCalendar_DateRef by value.
Definition bdlt_packedcalendar.h:1812
friend bool operator!=(const PackedCalendar_BusinessDayConstIterator &, const PackedCalendar_BusinessDayConstIterator &)
PackedCalendar_BusinessDayConstIterator & operator=(const PackedCalendar_BusinessDayConstIterator &rhs)
bsl::bidirectional_iterator_tag iterator_category
Definition bdlt_packedcalendar.h:1816
friend bool operator==(const PackedCalendar_BusinessDayConstIterator &, const PackedCalendar_BusinessDayConstIterator &)
PackedCalendar_BusinessDayConstIterator & operator--()
Definition bdlt_packedcalendar.h:2200
PackedCalendar_DateRef operator*() const
Definition bdlt_packedcalendar.h:2211
~PackedCalendar_BusinessDayConstIterator()
Destroy this object.
Definition bdlt_packedcalendar.h:2183
Definition bdlt_packedcalendar.h:1436
PackedCalendar_DateProxy(const Date &date)
Create a proxy object for the specified date.
Definition bdlt_packedcalendar.h:1901
~PackedCalendar_DateProxy()
Destroy this object.
Definition bdlt_packedcalendar.h:1907
const Date * operator->() const
Definition bdlt_packedcalendar.h:1920
Definition bdlt_packedcalendar.h:1474
~PackedCalendar_DateRef()
Destroy this object.
Definition bdlt_packedcalendar.h:1944
PackedCalendar_DateProxy operator&() const
Return a proxy object to this object's referenced date.
Definition bdlt_packedcalendar.h:1950
PackedCalendar_DateRef(const Date &date)
Create a date reference object using the specified date.
Definition bdlt_packedcalendar.h:1931
Definition bdlt_packedcalendar.h:1628
friend bool operator!=(const PackedCalendar_HolidayCodeConstIterator &, const PackedCalendar_HolidayCodeConstIterator &)
friend bsl::ptrdiff_t operator-(const PackedCalendar_HolidayCodeConstIterator &, const PackedCalendar_HolidayCodeConstIterator &)
PackedCalendar_HolidayCodeConstIterator & operator=(const PackedCalendar_HolidayCodeConstIterator &rhs)
Definition bdlt_packedcalendar.h:2091
PackedCalendar_HolidayCodeConstIterator & operator--()
Definition bdlt_packedcalendar.h:2107
int value_type
Definition bdlt_packedcalendar.h:1656
int reference
The star operator returns an int by value.
Definition bdlt_packedcalendar.h:1661
~PackedCalendar_HolidayCodeConstIterator()
Destroy this object.
Definition bdlt_packedcalendar.h:2083
int operator*() const
Return the holiday code referenced by this iterator.
Definition bdlt_packedcalendar.h:2115
bsl::bidirectional_iterator_tag iterator_category
Definition bdlt_packedcalendar.h:1665
int difference_type
Definition bdlt_packedcalendar.h:1657
friend bool operator==(const PackedCalendar_HolidayCodeConstIterator &, const PackedCalendar_HolidayCodeConstIterator &)
int * pointer
Definition bdlt_packedcalendar.h:1658
PackedCalendar_HolidayCodeConstIterator & operator++()
Definition bdlt_packedcalendar.h:2099
Definition bdlt_packedcalendar.h:1510
PackedCalendar_HolidayConstIterator & operator--()
Definition bdlt_packedcalendar.h:2003
PackedCalendar_DateProxy pointer
Definition bdlt_packedcalendar.h:1539
PackedCalendar_HolidayConstIterator & operator++()
Definition bdlt_packedcalendar.h:1995
~PackedCalendar_HolidayConstIterator()
Destroy this object.
Definition bdlt_packedcalendar.h:1979
bsl::bidirectional_iterator_tag iterator_category
Definition bdlt_packedcalendar.h:1546
int difference_type
Definition bdlt_packedcalendar.h:1538
PackedCalendar_HolidayConstIterator & operator=(const PackedCalendar_HolidayConstIterator &rhs)
Definition bdlt_packedcalendar.h:1986
friend bool operator==(const PackedCalendar_HolidayConstIterator &, const PackedCalendar_HolidayConstIterator &)
Date value_type
Definition bdlt_packedcalendar.h:1537
PackedCalendar_DateRef operator*() const
Definition bdlt_packedcalendar.h:2011
friend bool operator!=(const PackedCalendar_HolidayConstIterator &, const PackedCalendar_HolidayConstIterator &)
PackedCalendar_DateRef reference
The star operator returns a PackedCalendar_DateRef by value.
Definition bdlt_packedcalendar.h:1542
PackedCalendar_DateProxy operator->() const
Return a date proxy for the holiday referenced by this iterator.
Definition bdlt_packedcalendar.h:2018
Definition bdlt_packedcalendar.h:592
void reserveHolidayCodeCapacity(int numHolidayCodes)
Definition bdlt_packedcalendar.h:2343
HolidayConstReverseIterator rbeginHolidays() const
Definition bdlt_packedcalendar.h:3106
int getNextBusinessDay(Date *nextBusinessDay, const Date &date) const
Definition bdlt_packedcalendar.h:2935
void addWeekendDays(const DayOfWeekSet &weekendDays)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
bool isBusinessDay(const Date &date) const
Definition bdlt_packedcalendar.h:2980
bdlt::CalendarReverseIteratorAdapter< HolidayConstIterator > HolidayConstReverseIterator
Definition bdlt_packedcalendar.h:639
PackedCalendar(bslma::Allocator *basicAllocator=0)
void addHoliday(const Date &date)
PackedCalendar_HolidayConstIterator HolidayConstIterator
Definition bdlt_packedcalendar.h:631
void unionBusinessDays(const PackedCalendar &other)
int numWeekendDaysInRange() const
PackedCalendar(const Date &firstDate, const Date &lastDate, bslma::Allocator *basicAllocator=0)
int numNonBusinessDays() const
void setValidRange(const Date &firstDate, const Date &lastDate)
friend bool operator!=(const PackedCalendar &, const PackedCalendar &)
const Date & firstDate() const
Definition bdlt_packedcalendar.h:2927
int numBusinessDays(const Date &beginDate, const Date &endDate) const
void addHolidayCode(const Date &date, int holidayCode)
int numHolidays() const
Definition bdlt_packedcalendar.h:3059
int getNextBusinessDay(Date *nextBusinessDay, const Date &date, int nth) const
int numHolidayCodesTotal() const
Definition bdlt_packedcalendar.h:3053
void removeHoliday(const Date &date)
WeekendDaysTransitionConstReverseIterator rendWeekendDaysTransitions() const
Definition bdlt_packedcalendar.h:3180
HolidayCodeConstReverseIterator rendHolidayCodes(const Date &date) const
Definition bdlt_packedcalendar.h:3146
int holidayCode(const Date &date, int index) const
Definition bdlt_packedcalendar.h:2962
WeekendDaysTransitionConstIterator endWeekendDaysTransitions() const
Definition bdlt_packedcalendar.h:2921
HolidayCodeConstIterator beginHolidayCodes(const Date &date) const
WeekendDaysTransitionSequence::const_iterator WeekendDaysTransitionConstIterator
Definition bdlt_packedcalendar.h:645
PackedCalendar_HolidayCodeConstIterator HolidayCodeConstIterator
Definition bdlt_packedcalendar.h:633
void removeHolidayCode(const Date &date, int holidayCode)
BusinessDayConstReverseIterator rendBusinessDays() const
Definition bdlt_packedcalendar.h:3130
BusinessDayConstReverseIterator rbeginBusinessDays() const
Definition bdlt_packedcalendar.h:3072
BusinessDayConstIterator endBusinessDays() const
Definition bdlt_packedcalendar.h:2877
void addWeekendDay(DayOfWeek::Enum weekendDay)
int numBusinessDays() const
Definition bdlt_packedcalendar.h:3047
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_packedcalendar.h:2353
void addWeekendDaysTransition(const Date &startDate, const DayOfWeekSet &weekendDays)
void reserveHolidayCapacity(int numHolidays)
Definition bdlt_packedcalendar.h:2334
bool isNonBusinessDay(const Date &date) const
Definition bdlt_packedcalendar.h:3009
HolidayConstIterator beginHolidays() const
Definition bdlt_packedcalendar.h:2850
const Date & lastDate() const
Definition bdlt_packedcalendar.h:3033
bdlt::CalendarReverseIteratorAdapter< HolidayCodeConstIterator > HolidayCodeConstReverseIterator
Definition bdlt_packedcalendar.h:642
WeekendDaysTransitionPrivate WeekendDaysTransition
Definition bdlt_packedcalendar.h:627
bool isHoliday(const Date &date) const
Definition bdlt_packedcalendar.h:2988
HolidayCodeConstReverseIterator rbeginHolidayCodes(const Date &date) const
Definition bdlt_packedcalendar.h:3088
void swap(PackedCalendar &other)
void intersectNonBusinessDays(const PackedCalendar &other)
WeekendDaysTransition weekendDaysTransition(int index) const
Definition bdlt_packedcalendar.h:3188
HolidayCodeConstIterator endHolidayCodes(const Date &date) const
HolidayConstIterator endHolidays() const
Definition bdlt_packedcalendar.h:2901
~PackedCalendar()
Destroy this object.
void unionNonBusinessDays(const PackedCalendar &other)
bool isInRange(const Date &date) const
Definition bdlt_packedcalendar.h:3003
void intersectBusinessDays(const PackedCalendar &other)
bsl::reverse_iterator< WeekendDaysTransitionSequence::const_iterator > WeekendDaysTransitionConstReverseIterator
Definition bdlt_packedcalendar.h:649
bdlt::CalendarReverseIteratorAdapter< BusinessDayConstIterator > BusinessDayConstReverseIterator
Definition bdlt_packedcalendar.h:636
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlt_packedcalendar.h:3199
int length() const
Definition bdlt_packedcalendar.h:3041
bdlt::Date holiday(int index) const
Definition bdlt_packedcalendar.h:2953
static int maxSupportedBdexVersion()
Definition bdlt_packedcalendar.h:3287
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_packedcalendar.h:3205
PackedCalendar(const PackedCalendar &original, bslma::Allocator *basicAllocator=0)
int addHolidayIfInRange(const Date &date)
Definition bdlt_packedcalendar.h:2324
int numWeekendDaysTransitions() const
Definition bdlt_packedcalendar.h:3065
PackedCalendar & operator=(const PackedCalendar &rhs)
WeekendDaysTransitionConstIterator beginWeekendDaysTransitions() const
Definition bdlt_packedcalendar.h:2870
BusinessDayConstIterator beginBusinessDays() const
Definition bdlt_packedcalendar.h:2826
HolidayConstReverseIterator rendHolidays() const
Definition bdlt_packedcalendar.h:3164
WeekendDaysTransitionConstReverseIterator rbeginWeekendDaysTransitions() const
Definition bdlt_packedcalendar.h:3122
friend bool operator==(const PackedCalendar &, const PackedCalendar &)
void addDay(const Date &date)
bool isWeekendDay(const Date &date) const
int numHolidayCodes(const Date &date) const
int addHolidayCodeIfInRange(const Date &date, int holidayCode)
Definition bdlt_packedcalendar.h:2314
PackedCalendar_BusinessDayConstIterator BusinessDayConstIterator
Definition bdlt_packedcalendar.h:629
friend void hashAppend(HASHALG &hashAlg, const PackedCalendar &)
Definition bslstl_pair.h:1210
Definition bslstl_vector.h:1025
AllocatorTraits::size_type size_type
Definition bslstl_vector.h:1052
VALUE_TYPE * iterator
Definition bslstl_vector.h:1057
VALUE_TYPE const * const_iterator
Definition bslstl_vector.h:1058
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PRECONDITIONS_END()
Definition bsls_preconditions.h:131
#define BSLS_PRECONDITIONS_BEGIN()
Definition bsls_preconditions.h:130
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
Definition bbldc_basicisma30360.h:112
Calendar_BusinessDayConstIter operator++(Calendar_BusinessDayConstIter &iterator, int)
Definition bdlt_calendar.h:2156
bool operator==(const Calendar &lhs, const Calendar &rhs)
Date operator-(const Date &date, int numDays)
bsl::ostream & operator<<(bsl::ostream &stream, const Calendar &calendar)
void hashAppend(HASHALG &hashAlg, const Calendar &object)
bool operator!=(const Calendar &lhs, const Calendar &rhs)
Calendar_BusinessDayConstIter operator--(Calendar_BusinessDayConstIter &iterator, int)
Definition bdlt_calendar.h:2165
Definition balxml_encoderoptions.h:68
static PackedIntArrayConstIterator< TYPE > upperBound(PackedIntArrayConstIterator< TYPE > first, PackedIntArrayConstIterator< TYPE > last, TYPE value)
Definition bdlc_packedintarrayutil.h:216
static PackedIntArrayConstIterator< TYPE > lowerBound(PackedIntArrayConstIterator< TYPE > first, PackedIntArrayConstIterator< TYPE > last, TYPE value)
Definition bdlc_packedintarrayutil.h:186
Enum
Enumerated day-of-week values.
Definition bdlt_dayofweek.h:123
TYPE first
Definition bslstl_pair.h:605
TYPE second
Definition bslstl_pair.h:908
Definition bslma_usesbslmaallocator.h:343