BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlt_timetable.h
Go to the documentation of this file.
1/// @file bdlt_timetable.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_timetable.h -*-C++-*-
8#ifndef INCLUDED_BDLT_TIMETABLE
9#define INCLUDED_BDLT_TIMETABLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_timetable bdlt_timetable
15/// @brief Provide a repository for accessing timetable information.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_timetable
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_timetable-purpose"> Purpose</a>
25/// * <a href="#bdlt_timetable-classes"> Classes </a>
26/// * <a href="#bdlt_timetable-description"> Description </a>
27/// * <a href="#bdlt_timetable-exception-safety-guarantees"> Exception-Safety Guarantees </a>
28/// * <a href="#bdlt_timetable-usage"> Usage </a>
29/// * <a href="#bdlt_timetable-example-1-exchange-schedule"> Example 1: Exchange Schedule </a>
30///
31/// # Purpose {#bdlt_timetable-purpose}
32/// Provide a repository for accessing timetable information.
33///
34/// # Classes {#bdlt_timetable-classes}
35///
36/// - bdlt::Timetable: repository for accessing timetable information
37/// - bdlt::TimetableTransition: datetime and transition code value
38///
39/// # Description {#bdlt_timetable-description}
40/// This component provides a value-semantic class,
41/// `bdlt::Timetable`, that represents a timetable of state transitions over a
42/// *valid* *range* of dates, an associated iterator,
43/// `bdlt::Timetable::const_iterator`, that provides non-modifiable access to
44/// the timetable's state transitions, and a class, `bdlt::TimetableTransition`,
45/// that represents a change of state at a datetime.
46///
47/// `bdlt::Timetable` is designed to be especially efficient at determining the
48/// state in effect at a given `bdlt::Datetime` value (within the valid range
49/// for a particular `bdlt::Timetable` object), and iterating through the state
50/// transitions.
51///
52/// `bdlt::TimetableTransition` consists of a `bdlt::Datetime` and a (single)
53/// non-negative integral code (of type `int`) that defines the "state" that
54/// becomes effective at that datetime. The meaning of the integral code
55/// ascribed to each transition is defined by the client. There can be at most
56/// one `bdlt::TimetableTransition` defined for any datetime value within the
57/// range of a `bdlt::Timetable`. Consequently, there is at most one
58/// (client-defined) state in effect at any datetime in a timetable.
59///
60/// Default-constructed timetables are empty, and have an empty valid range.
61/// Timetables can also be constructed with an initial (non-empty) valid range.
62/// The `setValidRange` method modifies the valid range of a timetable, and a
63/// suite of "add" methods can be used to populate a timetable with state
64/// transitions.
65///
66/// Timetables are value-semantic objects, and, as such, necessarily support all
67/// of the standard value-semantic operations, such as default construction,
68/// copy construction and copy assignment, and equality comparison.
69///
70/// ## Exception-Safety Guarantees {#bdlt_timetable-exception-safety-guarantees}
71///
72///
73/// All methods of `bdlt::Timetable` are exception-safe, but in general provide
74/// only the basic guarantee (i.e., no guarantee of rollback): If an exception
75/// occurs (i.e., while attempting to allocate memory), the timetable object is
76/// left in a coherent state, but (unless otherwise specified) its *value* is
77/// undefined.
78///
79/// All methods of `bdlt::TimetableTransition` are exception-safe.
80///
81/// ## Usage {#bdlt_timetable-usage}
82///
83///
84/// This section illustrates intended use of this component.
85///
86/// ### Example 1: Exchange Schedule {#bdlt_timetable-example-1-exchange-schedule}
87///
88///
89/// Suppose we want to track the open and close times for an exchange. Most
90/// Mondays (and Tuesdays, Wednesdays, etc.) will have the same schedule,
91/// although some may differ. We can use `bdlt::Timetable` to efficiently store
92/// this data.
93///
94/// First, we create an instance of `bdlt::Timetable` with the desired valid
95/// range:
96/// @code
97/// bdlt::Timetable timetable(bdlt::Date(2018, 1, 1),
98/// bdlt::Date(2018, 12, 31));
99/// @endcode
100/// Then, we define the codes for start-of-trading and end-of-trading and
101/// populate the typical transitions into the timetable:
102/// @code
103/// const int k_TRADING = 0;
104/// const int k_NO_TRADING = 1;
105///
106/// timetable.setInitialTransitionCode(k_NO_TRADING);
107///
108/// for (int i = 0; i < 5; ++ i) {
109/// timetable.addTransitions(static_cast<bdlt::DayOfWeek::Enum>(
110/// bdlt::DayOfWeek::e_MON + i),
111/// bdlt::Time(8, 30),
112/// k_TRADING,
113/// timetable.firstDate(),
114/// timetable.lastDate());
115///
116/// timetable.addTransitions(static_cast<bdlt::DayOfWeek::Enum>(
117/// bdlt::DayOfWeek::e_MON + i),
118/// bdlt::Time(16, 30),
119/// k_NO_TRADING,
120/// timetable.firstDate(),
121/// timetable.lastDate());
122/// }
123/// @endcode
124/// Next, we add a holiday on January 19, 2018:
125/// @code
126/// timetable.removeTransitions(bdlt::Date(2018, 1, 19));
127/// @endcode
128/// Then, we add a half-day on November 23, 2018:
129/// @code
130/// timetable.addTransition(bdlt::Datetime(2018, 11, 23, 12, 30),
131/// k_NO_TRADING);
132///
133/// timetable.removeTransition(bdlt::Datetime(2018, 11, 23, 16, 30));
134/// @endcode
135/// Finally, we verify the transition code in effect at a few datetimes.
136/// @code
137/// assert(k_NO_TRADING == timetable.transitionCodeInEffect(
138/// bdlt::Datetime(2018, 1, 15, 8, 0)));
139///
140/// assert(k_TRADING == timetable.transitionCodeInEffect(
141/// bdlt::Datetime(2018, 1, 15, 8, 30)));
142///
143/// assert(k_TRADING == timetable.transitionCodeInEffect(
144/// bdlt::Datetime(2018, 1, 15, 16, 0)));
145///
146/// assert(k_NO_TRADING == timetable.transitionCodeInEffect(
147/// bdlt::Datetime(2018, 1, 15, 16, 30)));
148///
149/// assert(k_NO_TRADING == timetable.transitionCodeInEffect(
150/// bdlt::Datetime(2018, 11, 23, 8, 0)));
151///
152/// assert(k_TRADING == timetable.transitionCodeInEffect(
153/// bdlt::Datetime(2018, 11, 23, 8, 30)));
154///
155/// assert(k_TRADING == timetable.transitionCodeInEffect(
156/// bdlt::Datetime(2018, 11, 23, 12, 0)));
157///
158/// assert(k_NO_TRADING == timetable.transitionCodeInEffect(
159/// bdlt::Datetime(2018, 11, 23, 12, 30)));
160/// @endcode
161/// @}
162/** @} */
163/** @} */
164
165/** @addtogroup bdl
166 * @{
167 */
168/** @addtogroup bdlt
169 * @{
170 */
171/** @addtogroup bdlt_timetable
172 * @{
173 */
174
175#include <bdlscm_version.h>
176
177#include <bdlt_date.h>
178#include <bdlt_datetime.h>
179#include <bdlt_dayofweek.h>
180#include <bdlt_time.h>
181
182#include <bdlc_compactedarray.h>
183
184#include <bslalg_swaputil.h>
185
186#include <bslh_hash.h>
187
188#include <bslma_allocator.h>
190
191#include <bsls_assert.h>
192#include <bsls_review.h>
193
194#include <bsl_algorithm.h>
195#include <bsl_cstddef.h>
196#include <bsl_iosfwd.h>
197#include <bsl_vector.h>
198
199
200namespace bdlt {
201
202// FORWARD DECLARATIONS
203class Timetable;
204class Timetable_Day;
205class Timetable_ConstIterator;
206
207 // =========================
208 // class TimetableTransition
209 // =========================
210
211/// This simply-constrained attribute class represents a state transition,
212/// implemented as a datetime for when the transition occurs, and a code to
213/// indicate the new state.
214///
215/// See @ref bdlt_timetable
217
218 // DATA
219 Datetime d_datetime; // datetime of the transition
220 int d_code; // code in effect at, and after, 'd_datetime'
221
222 // FRIENDS
225
226 private:
227 // PRIVATE CREATORS
228
229 /// Create a `TimetableTransition` having datetime value
230 /// `Datetime(Date())` and code `k_UNSET_TRANSITION_CODE`.
232
233 /// Create a `TimetableTransition` having the specified `datetime` and `code`.
234 ///
235 /// \pre The behavior is undefined unless `24 > datetime.hour()` and
236 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
238
239 public:
240 // CONSTANTS
241 enum { k_UNSET_TRANSITION_CODE = -1 }; // value representing an unset
242 // transition code
243
244 // CREATORS
245
246 /// Create a `TimetableTransition` having the same value as the
247 /// specified `original` object.
249
250 /// Destroy this object.
252
253 // MANIPULATORS
254
255 /// Assign to this object the value of the specified `rhs` timetable
256 /// transition, and return a reference providing modifiable access to
257 /// this object.
259
260 // ACCESSORS
261
262 /// Return the datetime of this transition.
263 const Datetime& datetime() const;
264
265 /// Return the code of this transition.
266 int code() const;
267
268 // Aspects
269
270 /// Format this object to the specified output `stream` at the (absolute
271 /// value of) the optionally specified indentation `level` and return a
272 /// reference to the modifiable `stream`. If `level` is specified,
273 /// optionally specify `spacesPerLevel`, the number of spaces per
274 /// indentation level for this and all of its nested objects. If
275 /// `level` is negative, suppress indentation of the first line. If
276 /// `spacesPerLevel` is negative, format the entire output on one line,
277 /// suppressing all but the initial indentation (as governed by
278 /// `level`). If `stream` is not valid on entry, this operation has no
279 /// effect.
280 bsl::ostream& print(bsl::ostream& stream,
281 int level = 0,
282 int spacesPerLevel = 4) const;
283};
284
285// FREE OPERATORS
286
287/// Return `true` if the specified `lhs` and `rhs` timetable transitions
288/// have the same value, and `false` otherwise. Two timetable transitions
289/// have the same value if they have the same datetime and code.
290bool operator==(const TimetableTransition& lhs,
291 const TimetableTransition& rhs);
292
293/// Return `true` if the specified `lhs` and `rhs` timetable transitions do
294/// not have the same value, and `false` otherwise. Two timetable
295/// transitions do not have the same value if they do not have the same
296/// datetime or the same code.
297bool operator!=(const TimetableTransition& lhs,
298 const TimetableTransition& rhs);
299
300/// Return `true` if the specified `lhs` has a value less than the specified
301/// `rhs`, and `false` otherwise. Timetable transition `lhs` has a value
302/// less than timetable transition `rhs` if
303/// `lhs.datetime() < rhs.datetime()`, or `lhs.datetime() == rhs.datetime()`
304/// and `lhs.code() < rhs.code()`.
305bool operator<(const TimetableTransition& lhs,
306 const TimetableTransition& rhs);
307
308/// Return `true` if the specified `lhs` has a value less than the specified
309/// `rhs`, and `false` otherwise. Timetable transition `lhs` has a value
310/// less than datetime `rhs` if `lhs.datetime() < rhs`.
311///
312/// \pre The behavior is undefined unless `24 > rhs.hour()`.
313bool operator<(const TimetableTransition& lhs, const Datetime& rhs);
314
315/// Return `true` if the specified `lhs` has a value less than the specified
316/// `rhs`, and `false` otherwise. Datetime `lhs` has a value less than
317/// timetable transition `rhs` if `lhs < rhs.datetime()`.
318///
319/// \pre The behavior is undefined unless `24 > lhs.hour()`.
320bool operator<(const Datetime& lhs, const TimetableTransition& rhs);
321
322// HASH SPECIALIZATIONS
323
324/// Pass the specified `object` to the specified `hashAlg`. This function
325/// integrates with the `bslh` modular hashing system and effectively
326/// provides a `bsl::hash` specialization for `TimetableTransition`.
327template <class HASHALG>
328void hashAppend(HASHALG& hashAlg, const TimetableTransition& object);
329
330 // =============================
331 // class TimetableTransition_Ref
332 // =============================
333
334/// This private class is used by the arrow operator of the timetable
335/// iterator class. The objects instantiated from this class serve as
336/// references to `TimetableTransition` objects.
337///
338/// See @ref bdlt_timetable
340
342
343 private:
344 // NOT IMPLEMENTED
346
347 // PRIVATE CREATORS
348
349 /// Create a timetable transition reference object using the default
350 /// `TimetableTransition` constructor.
352
353 public:
354 // CREATORS
355
356 /// Create a timetable transition reference object using the specified
357 /// `transition`.
358 explicit TimetableTransition_Ref(const TimetableTransition& transition);
359
360 /// Create a timetable transition reference object having the value of
361 /// the specified `original` object.
363
365 // Destroy this object.
366
367 // MANIPULATORS
368
369 /// Assign to this object the value of the specified `rhs` timetable
370 /// transition, and return a reference providing modifiable access to
371 /// this `TimetableTransition_Ref`.
372 TimetableTransition_Ref& operator=(const TimetableTransition& rhs);
373};
374
375 // =====================================
376 // class Timetable_CompactableTransition
377 // =====================================
378
379/// This simply-constrained attribute class represents a state transition,
380/// implemented as a time for when the transition occurs, and a code to
381/// indicate the new state.
382///
383/// See @ref bdlt_timetable
385
386 // DATA
387 Time d_time; // time of the transition
388 int d_code; // code in effect at, and after, 'd_time'
389
390 // FRIENDS
391 friend class Timetable;
392 friend class Timetable_Day;
393
394 public:
395 // CONSTANTS
398 // value representing an unset
399 // transition code
400
401 // CREATORS
402
403 /// Create a `Timetable_CompactableTransition` having time value
404 /// `Time(0)` and code `k_UNSET_TRANSITION_CODE`.
406
407 /// Create a `Timetable_CompactableTransition` having the specified `time` and `code`.
408 ///
409 /// \pre The behavior is undefined unless
410 /// `24 > time.hour()` and
411 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
413
414 /// Create a `Timetable_CompactableTransition` having the same value as
415 /// the specified `original` object.
417 const Timetable_CompactableTransition& original);
418
420 // Destroy this object.
421
422 // MANIPULATORS
423
424 /// Assign to this object the value of the specified `rhs` compactable
425 /// transition, and return a reference providing modifiable access to
426 /// this object.
429
430 // ACCESSORS
431
432 /// Return the time of this compactable transition.
433 const Time& time() const;
434
435 /// Return the code of this compactable transition.
436 int code() const;
437
438 // Aspects
439
440 /// Format this object to the specified output `stream` at the (absolute
441 /// value of) the optionally specified indentation `level` and return a
442 /// reference to the modifiable `stream`. If `level` is specified,
443 /// optionally specify `spacesPerLevel`, the number of spaces per
444 /// indentation level for this and all of its nested objects. If
445 /// `level` is negative, suppress indentation of the first line. If
446 /// `spacesPerLevel` is negative, format the entire output on one line,
447 /// suppressing all but the initial indentation (as governed by
448 /// `level`). If `stream` is not valid on entry, this operation has no
449 /// effect.
450 bsl::ostream& print(bsl::ostream& stream,
451 int level = 0,
452 int spacesPerLevel = 4) const;
453};
454
455// FREE OPERATORS
456
457/// Return `true` if the specified `lhs` and `rhs` compactable transitions
458/// have the same value, and `false` otherwise. Two compactable transitions
459/// have the same value if they have the same time and code.
460bool operator==(const Timetable_CompactableTransition& lhs,
462
463/// Return `true` if the specified `lhs` and `rhs` compactable transitions
464/// do not have the same value, and `false` otherwise. Two compactable
465/// transitions do not have the same value if they do not have the same time
466/// or the same code.
467bool operator!=(const Timetable_CompactableTransition& lhs,
469
470/// Return `true` if the specified `lhs` has a value less than the specified
471/// `rhs`, and `false` otherwise. Compactable transition `lhs` has a value
472/// less than compactable transition `rhs` if `lhs.time() < rhs.time()`, or
473/// `lhs.time() == rhs.time()` and `lhs.code() < rhs.code()`.
474bool operator<(const Timetable_CompactableTransition& lhs,
476
477/// Return `true` if the specified `lhs` has a value less than the specified
478/// `rhs`, and `false` otherwise. Compactable transition `lhs` has a value
479/// less than time `rhs` if `lhs.time() < rhs`.
480///
481/// \pre The behavior is undefined unless `24 > rhs.hour()`.
482bool operator<(const Timetable_CompactableTransition& lhs,
483 const Time& rhs);
484
485/// Return `true` if the specified `lhs` has a value less than the specified
486/// `rhs`, and `false` otherwise. Time `lhs` has a value less than
487/// compactable transition `rhs` if `lhs < rhs.time()`.
488///
489/// \pre The behavior is undefined unless `24 > lhs.hour()`.
490bool operator<(const Time& lhs,
492
493// HASH SPECIALIZATIONS
494
495/// Pass the specified `object` to the specified `hashAlg`. This function
496/// integrates with the `bslh` modular hashing system and effectively
497/// provides a `bsl::hash` specialization for
498/// `Timetable_CompactableTransition`.
499template <class HASHALG>
500void hashAppend(HASHALG& hashAlg,
501 const Timetable_CompactableTransition& object);
502
503 // ===================
504 // class Timetable_Day
505 // ===================
506
507/// This class implements a value-semantic repository of time-indexed state
508/// transitions over one date (this class implements one day of a
509/// timetable). A `Timetable_Day` can be "populated" with state transitions
510/// via the `addTransition` method, and queried for the transition code in
511/// effect at a specified time via the `transitionCodeInEffect` method.
512///
513/// \note Note that, as an optimization for the `transitionCodeInEffect` method,
514/// the transition code in effect before the first possible transition is
515/// stored in `d_initialTransitionCode`.
516///
517/// See @ref bdlt_timetable
519
520 // DATA
521 int d_initialTransitionCode;
522 // transition code in effect at
523 // the start of this daily
524 // timetable
525
527 // ordered vector of transitions
528
529 // FRIENDS
531
532 friend bool operator==(const Timetable_Day&, const Timetable_Day&);
533 friend bool operator!=(const Timetable_Day&, const Timetable_Day&);
534 friend bool operator< (const Timetable_Day&, const Timetable_Day&);
535
536 template <class HASHALG>
537 friend void hashAppend(HASHALG&, const Timetable_Day&);
538
539 public:
540 // CONSTANTS
543 // value representing an unset
544 // transition code
545
546 // CREATORS
547
548 /// Create an empty `Timetable_Day` (i.e., a daily timetable having no
549 /// transitions) whose initial transition code is
550 /// `k_UNSET_TRANSITION_CODE`. Optionally specify a `basicAllocator`
551 /// used to supply memory. If `basicAllocator` is 0, the currently
552 /// installed default allocator is used.
553 explicit
554 Timetable_Day(bslma::Allocator *basicAllocator = 0);
555
556 /// Create a `Timetable_Day` having the same value as the specified
557 /// `original` object. Optionally specify a `basicAllocator` used to
558 /// supply memory. If `basicAllocator` is 0, the currently installed
559 /// default allocator is used.
560 Timetable_Day(const Timetable_Day& original,
561 bslma::Allocator *basicAllocator = 0);
562
563 ~Timetable_Day() = default;
564 // Destroy this object.
565
566 // MANIPULATORS
567
568 /// Assign to this object the value of the specified `rhs` daily
569 /// timetable, and return a reference providing modifiable access to
570 /// this object.
572
573 /// Add a transition to this daily timetable at the specified `time`
574 /// having the specified `code`. If `time` is already a transition
575 /// point, replace the existing code with `code`. Return `true` if the
576 /// value returned by `finalTransitionCode()` prior to this operation is
577 /// not equal to the value returned by `finalTransitionCode()` after
578 /// this operation, and `false` otherwise.
579 ///
580 /// \pre The behavior is undefined unless `24 > time.hour()` and
581 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
582 bool addTransition(const Time& time, int code);
583
584 /// Remove all transitions from this daily timetable. Return `true` if
585 /// the value returned by `finalTransitionCode()` prior to this
586 /// operation is not equal to the value returned by
587 /// `finalTransitionCode()` after this operation, and `false` otherwise.
589
590 /// If a transition occurs at the specified `time`, remove the
591 /// transition from this daily timetable. Otherwise, return without
592 /// modifying this daily timetable. Return `true` if the value returned
593 /// by `finalTransitionCode()` prior to this operation is not equal to
594 /// the value returned by `finalTransitionCode()` after this operation, and `false` otherwise.
595 ///
596 /// \pre The behavior is undefined unless
597 /// `24 > time.hour()`.
598 bool removeTransition(const Time& time);
599
600 /// Set the transition code in effect prior to the start of this daily
601 /// timetable to the specified `code`. Return `true` if the value
602 /// returned by `finalTransitionCode()` prior to this operation is not
603 /// equal to the value returned by `finalTransitionCode()` after this operation, and `false` otherwise.
604 ///
605 /// \pre The behavior is undefined unless
606 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
607 bool setInitialTransitionCode(int code);
608
609 // ACCESSORS
610
611 /// Return the transition code that is in effect at the end of this daily timetable.
612 ///
613 /// \note Note that if this daily timetable has no
614 /// transitions, `initialTransitionCode()` is returned.
615 int finalTransitionCode() const;
616
617 /// Return the transition code in effect prior to the start of this
618 /// daily timetable.
619 int initialTransitionCode() const;
620
621 /// Return the number of transitions in this daily timetable.
622 bsl::size_t size() const;
623
624 /// Return the transition code associated with the latest transition
625 /// that occurs on or before the specified `time` in this daily
626 /// timetable. If this daily timetable has no such transition, return `initialTransitionCode()`.
627 ///
628 /// \pre The behavior is undefined unless
629 /// `24 > time.hour()`.
630 int transitionCodeInEffect(const Time& time) const;
631};
632
633// FREE OPERATORS
634
635/// Return `true` if the specified `lhs` and `rhs` daily timetables have the
636/// same value, and `false` otherwise. Two daily timetables have the same
637/// value if they have the same initial transition code, the same number of
638/// transitions, and each corresponding pair of transitions has the same
639/// value.
640bool operator==(const Timetable_Day& lhs, const Timetable_Day& rhs);
641
642/// Return `true` if the specified `lhs` and `rhs` daily timetables do not
643/// have the same value, and `false` otherwise. Two daily timetables do not
644/// have the same value if they do not have the same initial transition
645/// code, they do not have the same number of transitions, or there is a
646/// corresponding pair of transitions that do not have the same value.
647bool operator!=(const Timetable_Day& lhs, const Timetable_Day& rhs);
648
649/// Return `true` if the specified `lhs` daily timetable is less than the
650/// specified `rhs` daily timetable, and `false` otherwise. The `lhs` daily
651/// timetable is less than the `rhs` daily timetable if
652/// `lhs.initialTransitionCode() < rhs.initialTransitionCode()`, or
653/// `lhs.initialTransitionCode() == rhs.initialTransitionCode()` and
654/// `lhs.d_transitions < rhs.d_transitions`.
655bool operator<(const Timetable_Day& lhs, const Timetable_Day& rhs);
656
657// HASH SPECIALIZATIONS
658
659/// Pass the specified `object` to the specified `hashAlg`. This function
660/// integrates with the `bslh` modular hashing system and effectively
661/// provides a `bsl::hash` specialization for `Timetable_Day`.
662template <class HASHALG>
663void hashAppend(HASHALG& hashAlg, const Timetable_Day& object);
664
665 // ===============
666 // class Timetable
667 // ===============
668
669/// This class implements a value-semantic repository of datetime-indexed
670/// state transitions over a *valid* *range* of dates. This valid range,
671/// `[firstDate() .. lastDate()]`, spans the first and last dates of a
672/// timetable's accessible contents. A timetable can be "populated" with state transitions via a suite of "add" methods.
673///
674/// \note Note that the behavior
675/// of requesting *any* timetable information for a supplied date whose
676/// value is outside the current *valid* *range* for that timetable is
677/// undefined.
678///
679/// See @ref bdlt_timetable
681
682 // DATA
683 Date d_firstDate; // start of valid range
684
685 Date d_lastDate; // end of valid range
686
687 int d_initialTransitionCode;
688 // transition code in
689 // effect *before* the
690 // valid range
691
692 bdlc::CompactedArray<Timetable_Day> d_timetable; // daily timetables
693
694 // FRIENDS
696
697 friend bool operator==(const Timetable&, const Timetable&);
698 friend bool operator!=(const Timetable&, const Timetable&);
699
700 template <class HASHALG>
701 friend void hashAppend(HASHALG&, const Timetable&);
702
703 public:
704 // CONSTANTS
707 // value representing an unset
708 // transition code
709
710 // TYPES
712
713 // CREATORS
714
715 /// Create an empty `Timetable` (i.e., a timetable having no
716 /// transitions) whose initial transition code is
717 /// `k_UNSET_TRANSITION_CODE`. Optionally specify a `basicAllocator`
718 /// used to supply memory. If `basicAllocator` is 0, the currently
719 /// installed default allocator is used.
720 explicit Timetable(bslma::Allocator *basicAllocator = 0);
721
722 /// Create a timetable having a valid range from the specified
723 /// `firstDate` through the specified `lastDate` and having the
724 /// optionally specified `initialTransitionCode`. If
725 /// `initialTransitionCode` is not specified, the initial transition
726 /// code is set to `k_UNSET_TRANSITION_CODE`. Optionally specify a
727 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
728 /// the currently installed default allocator is used.
729 ///
730 /// \pre The behavior is undefined unless `firstDate <= lastDate`, and
731 /// `0 <= initialTransitionCode` or
732 /// `k_UNSET_TRANSITION_CODE == initialTransitionCode`.
734 const Date& firstDate,
735 const Date& lastDate,
737 bslma::Allocator *basicAllocator = 0);
738
739 /// Create a timetable having the value of the specified `original`
740 /// timetable. Optionally specify a `basicAllocator` used to supply
741 /// memory. If `basicAllocator` is 0, the currently installed default
742 /// allocator is used.
743 Timetable(const Timetable& original, bslma::Allocator *basicAllocator = 0);
744
745 ~Timetable() = default;
746 // Destroy this object.
747
748 // MANIPULATORS
749
750 /// Assign to this timetable the value of the specified `rhs` timetable,
751 /// and return a reference providing modifiable access to this
752 /// timetable. This operation invalidates all iterators.
753 Timetable& operator=(const Timetable& rhs);
754
755 /// Add a transition to this timetable on the specified `date` at the
756 /// specified `time` having the specified `code`. If `time` is already
757 /// a transition point on `date`, replace the existing code with `code`.
758 /// The addition of a transition, but not the replacement of the code of
759 /// an existing transition, invalidates all iterators.
760 ///
761 /// \pre The behavior is undefined unless `24 > time.hour()`, `date` is within the valid
762 /// range of this timetable, and
763 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
764 void addTransition(const Date& date, const Time& time, int code);
765
766 /// Add a transition to this timetable at the specified `datetime`
767 /// having the specified `code`. If `datetime` is already a transition
768 /// point, replace the existing code with `code`. The addition of a
769 /// transition, but not the replacement of the code of an existing
770 /// transition, invalidates all iterators.
771 ///
772 /// \pre The behavior is undefined unless `24 > datetime.hour()`, `datetime.date()` is within the valid
773 /// range of this timetable, and
774 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
775 void addTransition(const Datetime& datetime, int code);
776
777 /// Add transitions to this timetable that occur at the specified
778 /// `time`, having the specified `code`, on all dates that are of the
779 /// specified `dayOfWeek` within the closed interval of dates from the
780 /// specified `firstDate` to the specified `lastDate`. For every date
781 /// on which this transition will occur, if `time` is already a
782 /// transition point, replace the existing code with `code`. The
783 /// addition of a transition, but not the replacement of the code of an
784 /// existing transition, invalidates all iterators.
785 ///
786 /// \pre The behavior is undefined unless `24 > time.hour()`, `firstDate <= lastDate`,
787 /// `firstDate` and `lastDate` are within the valid range of this
788 /// timetable, and `0 <= code || k_UNSET_TRANSITION_CODE == code`.
789 void addTransitions(const DayOfWeek::Enum& dayOfWeek,
790 const Time& time,
791 int code,
792 const Date& firstDate,
793 const Date& lastDate);
794
795 /// Remove all transitions from this timetable. The removal of a
796 /// transition invalidates all iterators.
798
799 /// If a transition occurs on the specified `date` at the specified
800 /// `time`, remove the transition from this timetable. Otherwise,
801 /// return without modifying this timetable. The removal of a
802 /// transition invalidates all iterators.
803 ///
804 /// \pre The behavior is undefined unless `24 > time.hour()` and `date` is within the valid range of
805 /// this timetable.
806 void removeTransition(const Date& date, const Time& time);
807
808 /// If a transition occurs at the specified `datetime`, remove the
809 /// transition from this timetable. Otherwise, return without modifying
810 /// this timetable. The removal of a transition invalidates all iterators.
811 ///
812 /// \pre The behavior is undefined unless `24 > datetime.hour()`
813 /// and `datetime.date()` is within the valid range of this timetable.
814 void removeTransition(const Datetime& datetime);
815
816 /// Remove all transitions from this timetable that occur on the
817 /// specified `date`. The removal of a transition invalidates all iterators.
818 ///
819 /// \pre The behavior is undefined unless `date` is within the
820 /// valid range of this timetable.
821 void removeTransitions(const Date& date);
822
823 /// Remove all transitions from this timetable that occur at the
824 /// specified `time` on all dates that are of the specified `dayOfWeek`
825 /// within the closed interval of dates from the specified `firstDate`
826 /// to the specified `lastDate`. The removal of a transition invalidates all iterators.
827 ///
828 /// \pre The behavior is undefined unless
829 /// `24 > time.hour()`, `firstDate <= lastDate`, and `firstDate` and
830 /// `lastDate` are within the valid range of this timetable.
831 void removeTransitions(const DayOfWeek::Enum& dayOfWeek,
832 const Time& time,
833 const Date& firstDate,
834 const Date& lastDate);
835
836 /// Reset this timetable to the default constructed (empty) state. All
837 /// associated iterators are invalidated.
838 void reset();
839
840 /// Set the transition code in effect at the start of this timetable to the specified `code`.
841 ///
842 /// \pre The behavior is undefined unless
843 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
845
846 /// Set the range of this timetable using the specified `firstDate` and
847 /// `lastDate` as, respectively, the first date and the last date of the
848 /// timetable. Any transitions, and associated transition codes, that
849 /// are outside of the new range are removed. The removal of a
850 /// transition invalidates all iterators.
851 ///
852 /// \pre The behavior is undefined unless `firstDate <= lastDate`.
854
855 // Aspects
856
857 /// Efficiently exchange the value of this object with the value of the
858 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
859 ///
860 /// \pre The behavior is undefined unless this
861 /// object was created with the same allocator as `other`.
862 void swap(Timetable& other);
863
864 // ACCESSORS
865
866 /// Return an iterator referring to the first transition in this
867 /// timetable, or the past-the-end iterator if this timetable is empty.
868 /// The iterator remains valid as long as this timetable exists, and the
869 /// number of transitions within this timetable does not change.
871
872 /// Return the past-the-end iterator for this timetable. The iterator
873 /// remains valid as long as this timetable exists, and the number of
874 /// transitions within this timetable does not change.
875 const_iterator end() const;
876
877 /// Return a `const` reference to the earliest date in the valid range of this timetable.
878 ///
879 /// \pre The behavior is undefined if this timetable does
880 /// not have a valid range (i.e., it is in the default constructed
881 /// (empty) state).
882 const Date& firstDate() const;
883
884 /// Return the transition code that is in effect at the start of this
885 /// timetable (see `setInitialTransitionCode`).
886 int initialTransitionCode() const;
887
888 /// Return `true` if the specified `date` is within the valid range of
889 /// this timetable, and `false` otherwise.
890 bool isInRange(const Date& date) const;
891
892 /// Return a `const` reference to the latest date in the valid range of this timetable.
893 ///
894 /// \pre The behavior is undefined if this timetable does
895 /// not have a valid range (i.e., it is in the default constructed
896 /// (empty) state).
897 const Date& lastDate() const;
898
899 /// Return the number of days in the valid range of this timetable,
900 /// which is defined to be 0 if this timetable is empty, and
901 /// `lastDate() - firstDate() + 1` otherwise.
902 int length() const;
903
904 /// Return the transition code associated with the latest transition
905 /// that occurs on or before the specified `date` and `time` in this
906 /// timetable. If this timetable has no such transition, return `initialTransitionCode()`.
907 ///
908 /// \pre The behavior is undefined unless
909 /// `24 > time.hour()` and `date` is within the valid range of this
910 /// timetable.
911 int transitionCodeInEffect(const Date& date, const Time& time) const;
912
913 /// Return the transition code associated with the latest transition
914 /// that occurs on or before the specified `datetime` in this timetable.
915 /// If this timetable has no such transition, return `initialTransitionCode()`.
916 ///
917 /// \pre The behavior is undefined unless
918 /// `24 > datetime.hour()` and `datetime.date()` is within the valid
919 /// range of this timetable.
920 int transitionCodeInEffect(const Datetime& datetime) const;
921
922 // Aspects
923
924 /// Return the allocator used by this object to supply memory.
926
927 /// Format this object to the specified output `stream` at the (absolute
928 /// value of) the optionally specified indentation `level` and return a
929 /// reference to the modifiable `stream`. If `level` is specified,
930 /// optionally specify `spacesPerLevel`, the number of spaces per
931 /// indentation level for this and all of its nested objects. If
932 /// `level` is negative, suppress indentation of the first line. If
933 /// `spacesPerLevel` is negative, format the entire output on one line,
934 /// suppressing all but the initial indentation (as governed by
935 /// `level`). If `stream` is not valid on entry, this operation has no
936 /// effect.
937 bsl::ostream& print(bsl::ostream& stream,
938 int level = 0,
939 int spacesPerLevel = 4) const;
940};
941
942// FREE OPERATORS
943
944/// Return `true` if the specified `lhs` and `rhs` timetables have the same
945/// value, and `false` otherwise. Two timetables have the same value if
946/// they have the same initial transition code, the same valid range (or are
947/// both empty), the same number of transitions, and each corresponding pair
948/// of transitions have the same value.
949bool operator==(const Timetable& lhs, const Timetable& rhs);
950
951/// Return `true` if the specified `lhs` and `rhs` timetables do not have
952/// the same value, and `false` otherwise. Two timetables do not have the
953/// same value if they do not have the same initial transition code, do not
954/// have the same valid range (and are not both empty), do not have the same
955/// number of transitions, or, for at least one corresponding pair of
956/// transitions, do not have the same value.
957bool operator!=(const Timetable& lhs, const Timetable& rhs);
958
959/// Write the value of the specified `timetable` to the specified output
960/// `stream`, and return a reference to the modifiable `stream`.
961bsl::ostream& operator<<(bsl::ostream& stream, const Timetable& timetable);
962
963// FREE FUNCTIONS
964
965/// Exchange the values of the specified `a` and `b` objects. This function
966/// provides the no-throw exception-safety guarantee if the two objects were
967/// created with the same allocator and the basic guarantee otherwise.
968void swap(Timetable& a, Timetable& b);
969
970// HASH SPECIALIZATIONS
971
972/// Pass the specified `object` to the specified `hashAlg`. This function
973/// integrates with the `bslh` modular hashing system and effectively
974/// provides a `bsl::hash` specialization for `Timetable`.
975template <class HASHALG>
976void hashAppend(HASHALG& hashAlg, const Timetable& object);
977
978 // =============================
979 // class Timetable_ConstIterator
980 // =============================
981
982/// Provide read-only, sequential access in increasing (chronological) order
983/// to the transitions in a `Timetable` object.
984///
985/// See @ref bdlt_timetable
987
988 // DATA
989 const Timetable *d_timetable_p; // pointer to the
990 // 'Timetable' into
991 // which this iterator
992 // references
993
994 bsl::size_t d_dayIndex; // index of the
995 // referenced daily
996 // timetable
997
998 bsl::size_t d_transitionIndex; // index of the
999 // referenced
1000 // transition in the
1001 // referenced daily
1002 // timetable
1003
1004 mutable TimetableTransition_Ref d_ref; // cached value used
1005 // for the return
1006 // value of
1007 // 'operator->()'
1008
1009 // FRIENDS
1010 friend class Timetable;
1011
1016
1017 private:
1018 // PRIVATE CREATORS
1019
1020 /// Create a transition iterator for the specified `timetable` that
1021 /// refers to the transition at the specified `transitionIndex` on the
1022 /// day at the specified `dayIndex` in `timetable`.
1023 Timetable_ConstIterator(const Timetable& timetable,
1024 bsl::size_t dayIndex,
1025 bsl::size_t transitionIndex);
1026
1027 public:
1028 // TYPES
1031
1032 /// The star operator returns a `TimetableTransition` *by* *value*.
1034
1035 // CREATORS
1036
1037 /// Create a default iterator.
1038 /// \note Note that the behavior of most methods
1039 /// is undefined when used on a default-constructed iterator.
1041
1042 /// Create an iterator having the value of the specified `original`
1043 /// iterator.
1045
1047 // Destroy this object.
1048
1049 // MANIPULATORS
1050
1051 /// Assign to this iterator the value of the specified `rhs` iterator,
1052 /// and return a reference providing modifiable access to this object.
1054
1055 /// Advance this iterator to refer to the next transition in the
1056 /// associated timetable, and return a reference providing modifiable access to this object.
1057 ///
1058 /// \pre The behavior is undefined unless, on entry,
1059 /// this iterator references a valid transition.
1061
1062 /// Regress this iterator to refer to the previous transition in the
1063 /// associated timetable, and return a reference providing modifiable access to this object.
1064 ///
1065 /// \pre The behavior is undefined unless, on entry,
1066 /// this iterator references a valid transition that is not the first
1067 /// transition of the associated timetable.
1069
1070 // ACCESSORS
1071
1072 /// Return, *by* *value*, a `TimetableTransition` object representing
1073 /// the transition referenced by this iterator.
1074 ///
1075 /// \pre The behavior is undefined unless this iterator references a valid transition in the
1076 /// associated timetable.
1078
1079 /// Return a proxy to the transition referenced by this iterator.
1080 ///
1081 /// \pre The behavior is undefined unless this iterator references a valid
1082 /// transition in the associated timetable.
1083 const TimetableTransition_Ref *operator->() const;
1084};
1085
1086// FREE OPERATORS
1087
1088/// Advance the specified `iterator` to refer to the next transition in the
1089/// referenced timetable, and return an iterator referring to the original element (*before* the advancement).
1090///
1091/// \pre The behavior is undefined unless,
1092/// on entry, `iterator` references a valid transition.
1094
1095/// Regress the specified `iterator` to refer to the previous transition in
1096/// the referenced timetable, and return an iterator referring to the
1097/// original element (*before* the decrementation).
1098///
1099/// \pre The behavior is undefined unless, on entry, `iterator` references a valid transition
1100/// that is not the first transition of the associated timetable.
1102
1103/// Return `true` if the specified `lhs` and `rhs` iterators have the same
1104/// value, and `false` otherwise. Two `Timetable_ConstIterator` iterators
1105/// have the same value if they refer to the same timetable and the same
1106/// transition.
1107bool operator==(const Timetable_ConstIterator& lhs,
1108 const Timetable_ConstIterator& rhs);
1109
1110/// Return `true` if the specified `lhs` and `rhs` iterators do not have the
1111/// same value, and `false` otherwise. Two `Timetable_ConstIterator`
1112/// iterators do not have the same value if they do not refer to the same
1113/// timetable, or do not refer to the same transition.
1114bool operator!=(const Timetable_ConstIterator& lhs,
1115 const Timetable_ConstIterator& rhs);
1116
1117// ============================================================================
1118// INLINE DEFINITIONS
1119// ============================================================================
1120
1121 // -------------------------
1122 // class TimetableTransition
1123 // -------------------------
1124
1125// PRIVATE CREATORS
1126inline
1127TimetableTransition::TimetableTransition()
1128: d_datetime(Date())
1129, d_code(k_UNSET_TRANSITION_CODE)
1130{
1131}
1132
1133inline
1134TimetableTransition::TimetableTransition(const Datetime& datetime, int code)
1135: d_datetime(datetime)
1136, d_code(code)
1137{
1138 BSLS_ASSERT(24 > datetime.hour());
1139
1140 BSLS_ASSERT(0 <= code || k_UNSET_TRANSITION_CODE == code);
1141}
1142
1143// CREATORS
1144inline
1145TimetableTransition::TimetableTransition(const TimetableTransition& original)
1146: d_datetime(original.d_datetime)
1147, d_code(original.d_code)
1148{
1149}
1150
1151// MANIPULATORS
1152inline
1154 const TimetableTransition& rhs)
1155{
1156 d_datetime = rhs.d_datetime;
1157 d_code = rhs.d_code;
1158
1159 return *this;
1160}
1161
1162// ACCESSORS
1163inline
1165{
1166 return d_datetime;
1167}
1168
1169inline
1171{
1172 return d_code;
1173}
1174
1175} // close package namespace
1176
1177// FREE OPERATORS
1178inline
1179bool bdlt::operator==(const TimetableTransition& lhs,
1180 const TimetableTransition& rhs)
1181{
1182 return lhs.datetime() == rhs.datetime() && lhs.code() == rhs.code();
1183}
1184
1185inline
1186bool bdlt::operator!=(const TimetableTransition& lhs,
1187 const TimetableTransition& rhs)
1188{
1189 return lhs.datetime() != rhs.datetime() || lhs.code() != rhs.code();
1190}
1191
1192inline
1193bool bdlt::operator<(const TimetableTransition& lhs,
1194 const TimetableTransition& rhs)
1195{
1196 return lhs.datetime() < rhs.datetime()
1197 || (lhs.datetime() == rhs.datetime() && lhs.code() < rhs.code());
1198}
1199
1200inline
1201bool bdlt::operator<(const TimetableTransition& lhs, const Datetime& rhs)
1202{
1203 BSLS_ASSERT(24 > rhs.hour());
1204
1205 return lhs.datetime() < rhs;
1206}
1207
1208inline
1209bool bdlt::operator<(const Datetime& lhs, const TimetableTransition& rhs)
1210{
1211 BSLS_ASSERT(24 > lhs.hour());
1212
1213 return lhs < rhs.datetime();
1214}
1215
1216// HASH SPECIALIZATIONS
1217template <class HASHALG>
1218inline
1219void bdlt::hashAppend(HASHALG& hashAlg, const TimetableTransition& object)
1220{
1221 using ::BloombergLP::bslh::hashAppend;
1222
1223 hashAppend(hashAlg, object.datetime());
1224 hashAppend(hashAlg, object.code());
1225}
1226
1227namespace bdlt {
1228
1229 // -----------------------------
1230 // class TimetableTransition_Ref
1231 // -----------------------------
1232
1233// PRIVATE CREATORS
1234inline
1235TimetableTransition_Ref::TimetableTransition_Ref()
1236: TimetableTransition()
1237{
1238}
1239
1240// CREATORS
1241inline
1242TimetableTransition_Ref::TimetableTransition_Ref(
1243 const TimetableTransition& transition)
1244: TimetableTransition(transition)
1245{
1246}
1247
1248inline
1249TimetableTransition_Ref::TimetableTransition_Ref(
1250 const TimetableTransition_Ref& original)
1251: TimetableTransition(original)
1252{
1253}
1254
1255// MANIPULATORS
1256inline
1257TimetableTransition_Ref& TimetableTransition_Ref::operator=(
1258 const TimetableTransition& rhs)
1259{
1260 d_datetime = rhs.d_datetime;
1261 d_code = rhs.d_code;
1262
1263 return *this;
1264}
1265
1266 // -------------------------------------
1267 // class Timetable_CompactableTransition
1268 // -------------------------------------
1269
1270// CREATORS
1271inline
1273: d_time(0)
1274, d_code(k_UNSET_TRANSITION_CODE)
1275{
1276}
1277
1278inline
1280 const Time& time,
1281 int code)
1282: d_time(time)
1283, d_code(code)
1284{
1285 BSLS_ASSERT(24 > time.hour());
1286
1288}
1289
1290inline
1292 const Timetable_CompactableTransition& original)
1293: d_time(original.d_time)
1294, d_code(original.d_code)
1295{
1296}
1297
1298// MANIPULATORS
1299inline
1302{
1303 d_time = rhs.d_time;
1304 d_code = rhs.d_code;
1305
1306 return *this;
1307}
1308
1309// ACCESSORS
1310inline
1312{
1313 return d_time;
1314}
1315
1316inline
1318{
1319 return d_code;
1320}
1321
1322} // close package namespace
1323
1324// FREE OPERATORS
1325inline
1326bool bdlt::operator==(const Timetable_CompactableTransition& lhs,
1327 const Timetable_CompactableTransition& rhs)
1328{
1329 return lhs.time() == rhs.time() && lhs.code() == rhs.code();
1330}
1331
1332inline
1333bool bdlt::operator!=(const Timetable_CompactableTransition& lhs,
1334 const Timetable_CompactableTransition& rhs)
1335{
1336 return lhs.time() != rhs.time() || lhs.code() != rhs.code();
1337}
1338
1339inline
1340bool bdlt::operator<(const Timetable_CompactableTransition& lhs,
1341 const Timetable_CompactableTransition& rhs)
1342{
1343 return lhs.time() < rhs.time()
1344 || (lhs.time() == rhs.time() && lhs.code() < rhs.code());
1345}
1346
1347inline
1348bool bdlt::operator<(const Timetable_CompactableTransition& lhs,
1349 const Time& rhs)
1350{
1351 BSLS_ASSERT(24 > rhs.hour());
1352
1353 return lhs.time() < rhs;
1354}
1355
1356inline
1357bool bdlt::operator<(const Time& lhs,
1358 const Timetable_CompactableTransition& rhs)
1359{
1360 BSLS_ASSERT(24 > lhs.hour());
1361
1362 return lhs < rhs.time();
1363}
1364
1365// HASH SPECIALIZATIONS
1366template <class HASHALG>
1367inline
1368void bdlt::hashAppend(HASHALG& hashAlg,
1369 const Timetable_CompactableTransition& object)
1370{
1371 using ::BloombergLP::bslh::hashAppend;
1372
1373 hashAppend(hashAlg, object.time());
1374 hashAppend(hashAlg, object.code());
1375}
1376
1377namespace bdlt {
1378
1379 // -------------------
1380 // class Timetable_Day
1381 // -------------------
1382
1383// CREATORS
1384inline
1386: d_initialTransitionCode(k_UNSET_TRANSITION_CODE)
1387, d_transitions(basicAllocator)
1388{
1389}
1390
1391inline
1393 bslma::Allocator *basicAllocator)
1394: d_initialTransitionCode(original.d_initialTransitionCode)
1395, d_transitions(original.d_transitions, basicAllocator)
1396{
1397}
1398
1399// MANIPULATORS
1400inline
1402{
1403 d_initialTransitionCode = rhs.d_initialTransitionCode;
1404 d_transitions = rhs.d_transitions;
1405
1406 return *this;
1407}
1408
1409inline
1411{
1412 int code = finalTransitionCode();
1413
1414 d_transitions.clear();
1415
1416 return code != d_initialTransitionCode;
1417}
1418
1419inline
1421{
1422 BSLS_ASSERT(0 <= code || k_UNSET_TRANSITION_CODE == code);
1423
1424 bool rv = d_initialTransitionCode != code && d_transitions.empty();
1425
1426 d_initialTransitionCode = code;
1427
1428 return rv;
1429}
1430
1431// ACCESSORS
1432inline
1434{
1436 d_transitions.rbegin();
1437
1438 return iter != d_transitions.rend()
1439 ? iter->d_code
1440 : d_initialTransitionCode;
1441}
1442
1443inline
1445{
1446 return d_initialTransitionCode;
1447}
1448
1449inline
1450bsl::size_t Timetable_Day::size() const
1451{
1452 return d_transitions.size();
1453}
1454
1455} // close package namespace
1456
1457// FREE OPERATORS
1458inline
1459bool bdlt::operator==(const Timetable_Day& lhs, const Timetable_Day& rhs)
1460{
1461 return lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1462 && lhs.d_transitions == rhs.d_transitions;
1463}
1464
1465inline
1466bool bdlt::operator!=(const Timetable_Day& lhs, const Timetable_Day& rhs)
1467{
1468 return lhs.d_initialTransitionCode != rhs.d_initialTransitionCode
1469 || lhs.d_transitions != rhs.d_transitions;
1470}
1471
1472inline
1473bool bdlt::operator<(const Timetable_Day& lhs, const Timetable_Day& rhs)
1474{
1475 return lhs.d_initialTransitionCode < rhs.d_initialTransitionCode
1476 || ( lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1477 && lhs.d_transitions < rhs.d_transitions);
1478}
1479
1480// HASH SPECIALIZATIONS
1481template <class HASHALG>
1482inline
1483void bdlt::hashAppend(HASHALG& hashAlg, const Timetable_Day& object)
1484{
1485 using ::BloombergLP::bslh::hashAppend;
1486
1487 hashAppend(hashAlg, object.d_initialTransitionCode);
1488 hashAppend(hashAlg, object.d_transitions);
1489}
1490
1491namespace bdlt {
1492
1493 // ---------------
1494 // class Timetable
1495 // ---------------
1496
1497// MANIPULATORS
1498inline
1500{
1501 Timetable(rhs, allocator()).swap(*this);
1502
1503 return *this;
1504}
1505
1506inline
1507void Timetable::addTransition(const Datetime& datetime, int code)
1508{
1509 addTransition(datetime.date(), datetime.time(), code);
1510}
1511
1512inline
1514{
1515 Date firstDate = d_firstDate;
1516 Date lastDate = d_lastDate;
1517
1518 d_firstDate = Date(9999, 12, 31);
1519 d_lastDate = Date( 1, 1, 1);
1520
1521 d_timetable.removeAll();
1522
1524}
1525
1526inline
1528{
1529 removeTransition(datetime.date(), datetime.time());
1530}
1531
1532inline
1534{
1535 d_initialTransitionCode = k_UNSET_TRANSITION_CODE;
1536
1537 d_firstDate = Date(9999, 12, 31);
1538 d_lastDate = Date( 1, 1, 1);
1539
1540 d_timetable.removeAll();
1541}
1542
1543 // Aspects
1544
1545inline
1547{
1548 // Member 'swap' is undefined for objects with non-equal allocators.
1549
1550 BSLS_ASSERT(allocator() == other.allocator());
1551
1552 bslalg::SwapUtil::swap(&d_initialTransitionCode,
1553 &other.d_initialTransitionCode);
1554
1555 bslalg::SwapUtil::swap(&d_firstDate, &other.d_firstDate);
1556 bslalg::SwapUtil::swap(&d_lastDate, &other.d_lastDate);
1557 bslalg::SwapUtil::swap(&d_timetable, &other.d_timetable);
1558}
1559
1560// ACCESSORS
1561inline
1563{
1564 return Timetable_ConstIterator(*this, d_timetable.length(), 0);
1565}
1566
1567inline
1569{
1570 BSLS_ASSERT(0 < length());
1571
1572 return d_firstDate;
1573}
1574
1575inline
1577{
1578 return d_initialTransitionCode;
1579}
1580
1581inline
1582bool Timetable::isInRange(const Date& date) const
1583{
1584 return date >= d_firstDate && date <= d_lastDate;
1585}
1586
1587inline
1589{
1590 BSLS_ASSERT(0 < length());
1591
1592 return d_lastDate;
1593}
1594
1595inline
1597{
1598 return d_firstDate <= d_lastDate ? d_lastDate - d_firstDate + 1 : 0;
1599}
1600
1601inline
1602int Timetable::transitionCodeInEffect(const Date& date, const Time& time) const
1603{
1604 BSLS_ASSERT(24 > time.hour());
1605 BSLS_ASSERT(isInRange(date));
1606
1607 bsl::size_t index = date - d_firstDate;
1608 const Timetable_Day& daily = d_timetable[index];
1609
1610 return daily.transitionCodeInEffect(time);
1611}
1612
1613inline
1615{
1616 return transitionCodeInEffect(datetime.date(), datetime.time());
1617}
1618
1619 // Aspects
1620
1621inline
1623{
1624 return d_timetable.allocator();
1625}
1626
1627} // close package namespace
1628
1629// FREE OPERATORS
1630inline
1631bool bdlt::operator==(const Timetable& lhs, const Timetable& rhs)
1632{
1633 return lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1634 && lhs.d_firstDate == rhs.d_firstDate
1635 && lhs.d_lastDate == rhs.d_lastDate
1636 && lhs.d_timetable == rhs.d_timetable;
1637}
1638
1639inline
1640bool bdlt::operator!=(const Timetable& lhs, const Timetable& rhs)
1641{
1642 return lhs.d_initialTransitionCode != rhs.d_initialTransitionCode
1643 || lhs.d_firstDate != rhs.d_firstDate
1644 || lhs.d_lastDate != rhs.d_lastDate
1645 || lhs.d_timetable != rhs.d_timetable;
1646}
1647
1648inline
1649bsl::ostream& bdlt::operator<<(bsl::ostream& stream,
1650 const Timetable& timetable)
1651{
1652 return timetable.print(stream, 0, -1);
1653}
1654
1655// FREE FUNCTIONS
1656inline
1657void bdlt::swap(Timetable& a, Timetable& b)
1658{
1659 if (a.allocator() == b.allocator()) {
1660 a.swap(b);
1661
1662 return; // RETURN
1663 }
1664
1665 Timetable futureA(b, a.allocator());
1666 Timetable futureB(a, b.allocator());
1667
1668 futureA.swap(a);
1669 futureB.swap(b);
1670}
1671
1672// HASH SPECIALIZATIONS
1673template <class HASHALG>
1674inline
1675void bdlt::hashAppend(HASHALG& hashAlg, const Timetable& object)
1676{
1677 using ::BloombergLP::bslh::hashAppend;
1678
1679 hashAppend(hashAlg, object.d_firstDate);
1680 hashAppend(hashAlg, object.d_lastDate);
1681 hashAppend(hashAlg, object.d_initialTransitionCode);
1682 hashAppend(hashAlg, object.d_timetable);
1683}
1684
1685namespace bdlt {
1686
1687 // -----------------------------
1688 // class Timetable_ConstIterator
1689 // -----------------------------
1690
1691// PRIVATE CREATORS
1692inline
1694 const Timetable& timetable,
1695 bsl::size_t dayIndex,
1696 bsl::size_t transitionIndex)
1697: d_timetable_p(&timetable)
1698, d_dayIndex(dayIndex)
1699, d_transitionIndex(transitionIndex)
1700{
1701}
1702
1703// CREATORS
1704inline
1706: d_timetable_p(0)
1707, d_dayIndex(0)
1708, d_transitionIndex(0)
1709{
1710}
1711
1712inline
1714 const Timetable_ConstIterator& original)
1715: d_timetable_p(original.d_timetable_p)
1716, d_dayIndex(original.d_dayIndex)
1717, d_transitionIndex(original.d_transitionIndex)
1718{
1719}
1720
1721// MANIPULATORS
1722inline
1725{
1726 d_timetable_p = rhs.d_timetable_p;
1727 d_dayIndex = rhs.d_dayIndex;
1728 d_transitionIndex = rhs.d_transitionIndex;
1729
1730 return *this;
1731}
1732
1733// ACCESSORS
1734inline
1736{
1737 BSLS_ASSERT(d_timetable_p);
1738 BSLS_ASSERT(d_dayIndex
1739 < static_cast<bsl::size_t>(d_timetable_p->length()));
1740 BSLS_ASSERT(d_transitionIndex
1741 < d_timetable_p->d_timetable[d_dayIndex].size());
1742
1743 const Timetable_CompactableTransition& transition =
1744 d_timetable_p->d_timetable[d_dayIndex].d_transitions[
1745 d_transitionIndex];
1746 return TimetableTransition(
1747 Datetime(d_timetable_p->firstDate() + static_cast<int>(d_dayIndex),
1748 transition.time()),
1749 transition.code());
1750}
1751
1752inline
1754{
1755 BSLS_ASSERT(d_timetable_p);
1756 BSLS_ASSERT(d_dayIndex
1757 < static_cast<bsl::size_t>(d_timetable_p->length()));
1758
1759 d_ref = this->operator*();
1760 return &d_ref;
1761}
1762
1763} // close package namespace
1764
1765// FREE OPERATORS
1766inline
1768 Timetable_ConstIterator& iterator,
1769 int)
1770{
1771 const Timetable_ConstIterator curr = iterator;
1772 ++iterator;
1773 return curr;
1774}
1775
1776inline
1778 Timetable_ConstIterator& iterator,
1779 int)
1780{
1781 const Timetable_ConstIterator curr = iterator;
1782 --iterator;
1783 return curr;
1784}
1785
1786inline
1787bool bdlt::operator==(const Timetable_ConstIterator& lhs,
1788 const Timetable_ConstIterator& rhs)
1789{
1790 return lhs.d_timetable_p == rhs.d_timetable_p
1791 && lhs.d_dayIndex == rhs.d_dayIndex
1792 && lhs.d_transitionIndex == rhs.d_transitionIndex;
1793}
1794
1795inline
1796bool bdlt::operator!=(const Timetable_ConstIterator& lhs,
1797 const Timetable_ConstIterator& rhs)
1798{
1799 return lhs.d_timetable_p != rhs.d_timetable_p
1800 || lhs.d_dayIndex != rhs.d_dayIndex
1801 || lhs.d_transitionIndex != rhs.d_transitionIndex;
1802}
1803
1804
1805
1806// TRAITS
1807
1808
1809namespace bslma {
1810
1811template <>
1812struct UsesBslmaAllocator<bdlt::Timetable_Day> : bsl::true_type {};
1813
1814template <>
1816
1817} // close namespace bslma
1818
1819
1820#endif
1821
1822// ----------------------------------------------------------------------------
1823// Copyright 2018 Bloomberg Finance L.P.
1824//
1825// Licensed under the Apache License, Version 2.0 (the "License");
1826// you may not use this file except in compliance with the License.
1827// You may obtain a copy of the License at
1828//
1829// http://www.apache.org/licenses/LICENSE-2.0
1830//
1831// Unless required by applicable law or agreed to in writing, software
1832// distributed under the License is distributed on an "AS IS" BASIS,
1833// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1834// See the License for the specific language governing permissions and
1835// limitations under the License.
1836// ----------------------------- END-OF-FILE ----------------------------------
1837
1838/** @} */
1839/** @} */
1840/** @} */
Definition bdlc_compactedarray.h:697
Definition bdlt_date.h:294
Definition bdlt_datetime.h:330
Date date() const
Return the value of the "date" part of this object.
Definition bdlt_datetime.h:2234
Time time() const
Return the value of the "time" part of this object.
Definition bdlt_datetime.h:2345
Definition bdlt_time.h:195
int hour() const
Return the value of the hour attribute of this time object.
Definition bdlt_time.h:926
Definition bdlt_timetable.h:339
Definition bdlt_timetable.h:216
TimetableTransition & operator=(const TimetableTransition &rhs)
Definition bdlt_timetable.h:1153
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
int code() const
Return the code of this transition.
Definition bdlt_timetable.h:1170
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:241
const Datetime & datetime() const
Return the datetime of this transition.
Definition bdlt_timetable.h:1164
~TimetableTransition()=default
Destroy this object.
Definition bdlt_timetable.h:384
int code() const
Return the code of this compactable transition.
Definition bdlt_timetable.h:1317
const Time & time() const
Return the time of this compactable transition.
Definition bdlt_timetable.h:1311
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Timetable_CompactableTransition()
Definition bdlt_timetable.h:1272
Timetable_CompactableTransition & operator=(const Timetable_CompactableTransition &rhs)
Definition bdlt_timetable.h:1300
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:396
Definition bdlt_timetable.h:986
const TimetableTransition_Ref * operator->() const
Definition bdlt_timetable.h:1753
Timetable_ConstIterator & operator=(const Timetable_ConstIterator &rhs)
Definition bdlt_timetable.h:1724
friend bool operator==(const Timetable_ConstIterator &, const Timetable_ConstIterator &)
Timetable_ConstIterator()
Definition bdlt_timetable.h:1705
TimetableTransition operator*() const
Definition bdlt_timetable.h:1735
Timetable_ConstIterator & operator--()
TimetableTransition value_type
Definition bdlt_timetable.h:1029
TimetableTransition_Ref * pointer
Definition bdlt_timetable.h:1030
friend bool operator!=(const Timetable_ConstIterator &, const Timetable_ConstIterator &)
Timetable_ConstIterator & operator++()
TimetableTransition reference
The star operator returns a TimetableTransition by value.
Definition bdlt_timetable.h:1033
Definition bdlt_timetable.h:518
int initialTransitionCode() const
Definition bdlt_timetable.h:1444
friend bool operator!=(const Timetable_Day &, const Timetable_Day &)
friend void hashAppend(HASHALG &, const Timetable_Day &)
int transitionCodeInEffect(const Time &time) const
bool removeAllTransitions()
Definition bdlt_timetable.h:1410
bool setInitialTransitionCode(int code)
Definition bdlt_timetable.h:1420
~Timetable_Day()=default
bool addTransition(const Time &time, int code)
Timetable_Day & operator=(const Timetable_Day &rhs)
Definition bdlt_timetable.h:1401
bool removeTransition(const Time &time)
int finalTransitionCode() const
Definition bdlt_timetable.h:1433
bsl::size_t size() const
Return the number of transitions in this daily timetable.
Definition bdlt_timetable.h:1450
Timetable_Day(bslma::Allocator *basicAllocator=0)
Definition bdlt_timetable.h:1385
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:541
friend bool operator<(const Timetable_Day &, const Timetable_Day &)
friend bool operator==(const Timetable_Day &, const Timetable_Day &)
Definition bdlt_timetable.h:680
int transitionCodeInEffect(const Date &date, const Time &time) const
Definition bdlt_timetable.h:1602
~Timetable()=default
Timetable_ConstIterator const_iterator
Definition bdlt_timetable.h:711
void addTransition(const Date &date, const Time &time, int code)
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlt_timetable.h:1622
friend bool operator==(const Timetable &, const Timetable &)
void setInitialTransitionCode(int code)
void addTransitions(const DayOfWeek::Enum &dayOfWeek, const Time &time, int code, const Date &firstDate, const Date &lastDate)
friend void hashAppend(HASHALG &, const Timetable &)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Timetable(bslma::Allocator *basicAllocator=0)
Timetable(const Timetable &original, bslma::Allocator *basicAllocator=0)
void swap(Timetable &other)
Definition bdlt_timetable.h:1546
friend class Timetable_ConstIterator
Definition bdlt_timetable.h:695
int initialTransitionCode() const
Definition bdlt_timetable.h:1576
void setValidRange(const Date &firstDate, const Date &lastDate)
Timetable(const Date &firstDate, const Date &lastDate, int initialTransitionCode=k_UNSET_TRANSITION_CODE, bslma::Allocator *basicAllocator=0)
bool isInRange(const Date &date) const
Definition bdlt_timetable.h:1582
const_iterator end() const
Definition bdlt_timetable.h:1562
void reset()
Definition bdlt_timetable.h:1533
friend bool operator!=(const Timetable &, const Timetable &)
void removeTransitions(const Date &date)
const Date & lastDate() const
Definition bdlt_timetable.h:1588
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:705
void removeTransition(const Date &date, const Time &time)
const Date & firstDate() const
Definition bdlt_timetable.h:1568
int length() const
Definition bdlt_timetable.h:1596
const_iterator begin() const
void removeTransitions(const DayOfWeek::Enum &dayOfWeek, const Time &time, const Date &firstDate, const Date &lastDate)
void removeAllTransitions()
Definition bdlt_timetable.h:1513
Timetable & operator=(const Timetable &rhs)
Definition bdlt_timetable.h:1499
Definition bslstl_vector.h:1120
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_vector.h:1155
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:182
Definition bslma_allocator.h:545
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
Definition bbldc_basicisma30360.h:112
bool operator<(const Date &lhs, const Date &rhs)
Calendar_BusinessDayConstIter operator++(Calendar_BusinessDayConstIter &iterator, int)
Definition bdlt_calendar.h:2215
bool operator==(const Calendar &lhs, const Calendar &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const Calendar &calendar)
void swap(Calendar &a, Calendar &b)
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:2224
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition baljsn_encoder_testtypes.h:76
Enum
Enumerated day-of-week values.
Definition bdlt_dayofweek.h:125
Definition bslma_usesbslmaallocator.h:344