BDE 4.14.0 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
234 /// `code`. The behavior is undefined unless `24 > datetime.hour()` and
235 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
237
238 public:
239 // CONSTANTS
240 enum { k_UNSET_TRANSITION_CODE = -1 }; // value representing an unset
241 // transition code
242
243 // CREATORS
244
245 /// Create a `TimetableTransition` having the same value as the
246 /// specified `original` object.
248
249 /// Destroy this object.
251
252 // MANIPULATORS
253
254 /// Assign to this object the value of the specified `rhs` timetable
255 /// transition, and return a reference providing modifiable access to
256 /// this object.
258
259 // ACCESSORS
260
261 /// Return the datetime of this transition.
262 const Datetime& datetime() const;
263
264 /// Return the code of this transition.
265 int code() const;
266
267 // Aspects
268
269 /// Format this object to the specified output `stream` at the (absolute
270 /// value of) the optionally specified indentation `level` and return a
271 /// reference to the modifiable `stream`. If `level` is specified,
272 /// optionally specify `spacesPerLevel`, the number of spaces per
273 /// indentation level for this and all of its nested objects. If
274 /// `level` is negative, suppress indentation of the first line. If
275 /// `spacesPerLevel` is negative, format the entire output on one line,
276 /// suppressing all but the initial indentation (as governed by
277 /// `level`). If `stream` is not valid on entry, this operation has no
278 /// effect.
279 bsl::ostream& print(bsl::ostream& stream,
280 int level = 0,
281 int spacesPerLevel = 4) const;
282};
283
284// FREE OPERATORS
285
286/// Return `true` if the specified `lhs` and `rhs` timetable transitions
287/// have the same value, and `false` otherwise. Two timetable transitions
288/// have the same value if they have the same datetime and code.
289bool operator==(const TimetableTransition& lhs,
290 const TimetableTransition& rhs);
291
292/// Return `true` if the specified `lhs` and `rhs` timetable transitions do
293/// not have the same value, and `false` otherwise. Two timetable
294/// transitions do not have the same value if they do not have the same
295/// datetime or the same code.
296bool operator!=(const TimetableTransition& lhs,
297 const TimetableTransition& rhs);
298
299/// Return `true` if the specified `lhs` has a value less than the specified
300/// `rhs`, and `false` otherwise. Timetable transition `lhs` has a value
301/// less than timetable transition `rhs` if
302/// `lhs.datetime() < rhs.datetime()`, or `lhs.datetime() == rhs.datetime()`
303/// and `lhs.code() < rhs.code()`.
304bool operator<(const TimetableTransition& lhs,
305 const TimetableTransition& rhs);
306
307/// Return `true` if the specified `lhs` has a value less than the specified
308/// `rhs`, and `false` otherwise. Timetable transition `lhs` has a value
309/// less than datetime `rhs` if `lhs.datetime() < rhs`. The behavior is
310/// undefined unless `24 > rhs.hour()`.
311bool operator<(const TimetableTransition& lhs, const Datetime& rhs);
312
313/// Return `true` if the specified `lhs` has a value less than the specified
314/// `rhs`, and `false` otherwise. Datetime `lhs` has a value less than
315/// timetable transition `rhs` if `lhs < rhs.datetime()`. The behavior is
316/// undefined unless `24 > lhs.hour()`.
317bool operator<(const Datetime& lhs, const TimetableTransition& rhs);
318
319// HASH SPECIALIZATIONS
320
321/// Pass the specified `object` to the specified `hashAlg`. This function
322/// integrates with the `bslh` modular hashing system and effectively
323/// provides a `bsl::hash` specialization for `TimetableTransition`.
324template <class HASHALG>
325void hashAppend(HASHALG& hashAlg, const TimetableTransition& object);
326
327 // =============================
328 // class TimetableTransition_Ref
329 // =============================
330
331/// This private class is used by the arrow operator of the timetable
332/// iterator class. The objects instantiated from this class serve as
333/// references to `TimetableTransition` objects.
334///
335/// See @ref bdlt_timetable
337
339
340 private:
341 // NOT IMPLEMENTED
343
344 // PRIVATE CREATORS
345
346 /// Create a timetable transition reference object using the default
347 /// `TimetableTransition` constructor.
349
350 public:
351 // CREATORS
352
353 /// Create a timetable transition reference object using the specified
354 /// `transition`.
355 explicit TimetableTransition_Ref(const TimetableTransition& transition);
356
357 /// Create a timetable transition reference object having the value of
358 /// the specified `original` object.
360
362 // Destroy this object.
363
364 // MANIPULATORS
365
366 /// Assign to this object the value of the specified `rhs` timetable
367 /// transition, and return a reference providing modifiable access to
368 /// this `TimetableTransition_Ref`.
369 TimetableTransition_Ref& operator=(const TimetableTransition& rhs);
370};
371
372 // =====================================
373 // class Timetable_CompactableTransition
374 // =====================================
375
376/// This simply-constrained attribute class represents a state transition,
377/// implemented as a time for when the transition occurs, and a code to
378/// indicate the new state.
379///
380/// See @ref bdlt_timetable
382
383 // DATA
384 Time d_time; // time of the transition
385 int d_code; // code in effect at, and after, 'd_time'
386
387 // FRIENDS
388 friend class Timetable;
389 friend class Timetable_Day;
390
391 public:
392 // CONSTANTS
395 // value representing an unset
396 // transition code
397
398 // CREATORS
399
400 /// Create a `Timetable_CompactableTransition` having time value
401 /// `Time(0)` and code `k_UNSET_TRANSITION_CODE`.
403
404 /// Create a `Timetable_CompactableTransition` having the specified
405 /// `time` and `code`. The behavior is undefined unless
406 /// `24 > time.hour()` and
407 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
409
410 /// Create a `Timetable_CompactableTransition` having the same value as
411 /// the specified `original` object.
413 const Timetable_CompactableTransition& original);
414
416 // Destroy this object.
417
418 // MANIPULATORS
419
420 /// Assign to this object the value of the specified `rhs` compactable
421 /// transition, and return a reference providing modifiable access to
422 /// this object.
425
426 // ACCESSORS
427
428 /// Return the time of this compactable transition.
429 const Time& time() const;
430
431 /// Return the code of this compactable transition.
432 int code() const;
433
434 // Aspects
435
436 /// Format this object to the specified output `stream` at the (absolute
437 /// value of) the optionally specified indentation `level` and return a
438 /// reference to the modifiable `stream`. If `level` is specified,
439 /// optionally specify `spacesPerLevel`, the number of spaces per
440 /// indentation level for this and all of its nested objects. If
441 /// `level` is negative, suppress indentation of the first line. If
442 /// `spacesPerLevel` is negative, format the entire output on one line,
443 /// suppressing all but the initial indentation (as governed by
444 /// `level`). If `stream` is not valid on entry, this operation has no
445 /// effect.
446 bsl::ostream& print(bsl::ostream& stream,
447 int level = 0,
448 int spacesPerLevel = 4) const;
449};
450
451// FREE OPERATORS
452
453/// Return `true` if the specified `lhs` and `rhs` compactable transitions
454/// have the same value, and `false` otherwise. Two compactable transitions
455/// have the same value if they have the same time and code.
456bool operator==(const Timetable_CompactableTransition& lhs,
458
459/// Return `true` if the specified `lhs` and `rhs` compactable transitions
460/// do not have the same value, and `false` otherwise. Two compactable
461/// transitions do not have the same value if they do not have the same time
462/// or the same code.
463bool operator!=(const Timetable_CompactableTransition& lhs,
465
466/// Return `true` if the specified `lhs` has a value less than the specified
467/// `rhs`, and `false` otherwise. Compactable transition `lhs` has a value
468/// less than compactable transition `rhs` if `lhs.time() < rhs.time()`, or
469/// `lhs.time() == rhs.time()` and `lhs.code() < rhs.code()`.
470bool operator<(const Timetable_CompactableTransition& lhs,
472
473/// Return `true` if the specified `lhs` has a value less than the specified
474/// `rhs`, and `false` otherwise. Compactable transition `lhs` has a value
475/// less than time `rhs` if `lhs.time() < rhs`. The behavior is undefined
476/// unless `24 > rhs.hour()`.
477bool operator<(const Timetable_CompactableTransition& lhs,
478 const Time& rhs);
479
480/// Return `true` if the specified `lhs` has a value less than the specified
481/// `rhs`, and `false` otherwise. Time `lhs` has a value less than
482/// compactable transition `rhs` if `lhs < rhs.time()`. The behavior is
483/// undefined unless `24 > lhs.hour()`.
484bool operator<(const Time& lhs,
486
487// HASH SPECIALIZATIONS
488
489/// Pass the specified `object` to the specified `hashAlg`. This function
490/// integrates with the `bslh` modular hashing system and effectively
491/// provides a `bsl::hash` specialization for
492/// `Timetable_CompactableTransition`.
493template <class HASHALG>
494void hashAppend(HASHALG& hashAlg,
495 const Timetable_CompactableTransition& object);
496
497 // ===================
498 // class Timetable_Day
499 // ===================
500
501/// This class implements a value-semantic repository of time-indexed state
502/// transitions over one date (this class implements one day of a
503/// timetable). A `Timetable_Day` can be "populated" with state transitions
504/// via the `addTransition` method, and queried for the transition code in
505/// effect at a specified time via the `transitionCodeInEffect` method.
506/// Note that, as an optimization for the `transitionCodeInEffect` method,
507/// the transition code in effect before the first possible transition is
508/// stored in `d_initialTransitionCode`.
509///
510/// See @ref bdlt_timetable
512
513 // DATA
514 int d_initialTransitionCode;
515 // transition code in effect at
516 // the start of this daily
517 // timetable
518
520 // ordered vector of transitions
521
522 // FRIENDS
524
525 friend bool operator==(const Timetable_Day&, const Timetable_Day&);
526 friend bool operator!=(const Timetable_Day&, const Timetable_Day&);
527 friend bool operator< (const Timetable_Day&, const Timetable_Day&);
528
529 template <class HASHALG>
530 friend void hashAppend(HASHALG&, const Timetable_Day&);
531
532 public:
533 // CONSTANTS
536 // value representing an unset
537 // transition code
538
539 // CREATORS
540
541 /// Create an empty `Timetable_Day` (i.e., a daily timetable having no
542 /// transitions) whose initial transition code is
543 /// `k_UNSET_TRANSITION_CODE`. Optionally specify a `basicAllocator`
544 /// used to supply memory. If `basicAllocator` is 0, the currently
545 /// installed default allocator is used.
546 explicit
547 Timetable_Day(bslma::Allocator *basicAllocator = 0);
548
549 /// Create a `Timetable_Day` having the same value as the specified
550 /// `original` object. Optionally specify a `basicAllocator` used to
551 /// supply memory. If `basicAllocator` is 0, the currently installed
552 /// default allocator is used.
553 Timetable_Day(const Timetable_Day& original,
554 bslma::Allocator *basicAllocator = 0);
555
556 ~Timetable_Day() = default;
557 // Destroy this object.
558
559 // MANIPULATORS
560
561 /// Assign to this object the value of the specified `rhs` daily
562 /// timetable, and return a reference providing modifiable access to
563 /// this object.
565
566 /// Add a transition to this daily timetable at the specified `time`
567 /// having the specified `code`. If `time` is already a transition
568 /// point, replace the existing code with `code`. Return `true` if the
569 /// value returned by `finalTransitionCode()` prior to this operation is
570 /// not equal to the value returned by `finalTransitionCode()` after
571 /// this operation, and `false` otherwise. The behavior is undefined
572 /// unless `24 > time.hour()` and
573 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
574 bool addTransition(const Time& time, int code);
575
576 /// Remove all transitions from this daily timetable. Return `true` if
577 /// the value returned by `finalTransitionCode()` prior to this
578 /// operation is not equal to the value returned by
579 /// `finalTransitionCode()` after this operation, and `false` otherwise.
581
582 /// If a transition occurs at the specified `time`, remove the
583 /// transition from this daily timetable. Otherwise, return without
584 /// modifying this daily timetable. Return `true` if the value returned
585 /// by `finalTransitionCode()` prior to this operation is not equal to
586 /// the value returned by `finalTransitionCode()` after this operation,
587 /// and `false` otherwise. The behavior is undefined unless
588 /// `24 > time.hour()`.
589 bool removeTransition(const Time& time);
590
591 /// Set the transition code in effect prior to the start of this daily
592 /// timetable to the specified `code`. Return `true` if the value
593 /// returned by `finalTransitionCode()` prior to this operation is not
594 /// equal to the value returned by `finalTransitionCode()` after this
595 /// operation, and `false` otherwise. The behavior is undefined unless
596 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
597 bool setInitialTransitionCode(int code);
598
599 // ACCESSORS
600
601 /// Return the transition code that is in effect at the end of this
602 /// daily timetable. Note that if this daily timetable has no
603 /// transitions, `initialTransitionCode()` is returned.
604 int finalTransitionCode() const;
605
606 /// Return the transition code in effect prior to the start of this
607 /// daily timetable.
608 int initialTransitionCode() const;
609
610 /// Return the number of transitions in this daily timetable.
611 bsl::size_t size() const;
612
613 /// Return the transition code associated with the latest transition
614 /// that occurs on or before the specified `time` in this daily
615 /// timetable. If this daily timetable has no such transition, return
616 /// `initialTransitionCode()`. The behavior is undefined unless
617 /// `24 > time.hour()`.
618 int transitionCodeInEffect(const Time& time) const;
619};
620
621// FREE OPERATORS
622
623/// Return `true` if the specified `lhs` and `rhs` daily timetables have the
624/// same value, and `false` otherwise. Two daily timetables have the same
625/// value if they have the same initial transition code, the same number of
626/// transitions, and each corresponding pair of transitions has the same
627/// value.
628bool operator==(const Timetable_Day& lhs, const Timetable_Day& rhs);
629
630/// Return `true` if the specified `lhs` and `rhs` daily timetables do not
631/// have the same value, and `false` otherwise. Two daily timetables do not
632/// have the same value if they do not have the same initial transition
633/// code, they do not have the same number of transitions, or there is a
634/// corresponding pair of transitions that do not have the same value.
635bool operator!=(const Timetable_Day& lhs, const Timetable_Day& rhs);
636
637/// Return `true` if the specified `lhs` daily timetable is less than the
638/// specified `rhs` daily timetable, and `false` otherwise. The `lhs` daily
639/// timetable is less than the `rhs` daily timetable if
640/// `lhs.initialTransitionCode() < rhs.initialTransitionCode()`, or
641/// `lhs.initialTransitionCode() == rhs.initialTransitionCode()` and
642/// `lhs.d_transitions < rhs.d_transitions`.
643bool operator<(const Timetable_Day& lhs, const Timetable_Day& rhs);
644
645// HASH SPECIALIZATIONS
646
647/// Pass the specified `object` to the specified `hashAlg`. This function
648/// integrates with the `bslh` modular hashing system and effectively
649/// provides a `bsl::hash` specialization for `Timetable_Day`.
650template <class HASHALG>
651void hashAppend(HASHALG& hashAlg, const Timetable_Day& object);
652
653 // ===============
654 // class Timetable
655 // ===============
656
657/// This class implements a value-semantic repository of datetime-indexed
658/// state transitions over a *valid* *range* of dates. This valid range,
659/// `[firstDate() .. lastDate()]`, spans the first and last dates of a
660/// timetable's accessible contents. A timetable can be "populated" with
661/// state transitions via a suite of "add" methods. Note that the behavior
662/// of requesting *any* timetable information for a supplied date whose
663/// value is outside the current *valid* *range* for that timetable is
664/// undefined.
665///
666/// See @ref bdlt_timetable
668
669 // DATA
670 Date d_firstDate; // start of valid range
671
672 Date d_lastDate; // end of valid range
673
674 int d_initialTransitionCode;
675 // transition code in
676 // effect *before* the
677 // valid range
678
679 bdlc::CompactedArray<Timetable_Day> d_timetable; // daily timetables
680
681 // FRIENDS
683
684 friend bool operator==(const Timetable&, const Timetable&);
685 friend bool operator!=(const Timetable&, const Timetable&);
686
687 template <class HASHALG>
688 friend void hashAppend(HASHALG&, const Timetable&);
689
690 public:
691 // CONSTANTS
694 // value representing an unset
695 // transition code
696
697 // TYPES
699
700 // CREATORS
701
702 /// Create an empty `Timetable` (i.e., a timetable having no
703 /// transitions) whose initial transition code is
704 /// `k_UNSET_TRANSITION_CODE`. Optionally specify a `basicAllocator`
705 /// used to supply memory. If `basicAllocator` is 0, the currently
706 /// installed default allocator is used.
707 explicit Timetable(bslma::Allocator *basicAllocator = 0);
708
709 /// Create a timetable having a valid range from the specified
710 /// `firstDate` through the specified `lastDate` and having the
711 /// optionally specified `initialTransitionCode`. If
712 /// `initialTransitionCode` is not specified, the initial transition
713 /// code is set to `k_UNSET_TRANSITION_CODE`. Optionally specify a
714 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
715 /// the currently installed default allocator is used. The behavior is
716 /// undefined unless `firstDate <= lastDate`, and
717 /// `0 <= initialTransitionCode` or
718 /// `k_UNSET_TRANSITION_CODE == initialTransitionCode`.
720 const Date& firstDate,
721 const Date& lastDate,
723 bslma::Allocator *basicAllocator = 0);
724
725 /// Create a timetable having the value of the specified `original`
726 /// timetable. Optionally specify a `basicAllocator` used to supply
727 /// memory. If `basicAllocator` is 0, the currently installed default
728 /// allocator is used.
729 Timetable(const Timetable& original, bslma::Allocator *basicAllocator = 0);
730
731 ~Timetable() = default;
732 // Destroy this object.
733
734 // MANIPULATORS
735
736 /// Assign to this timetable the value of the specified `rhs` timetable,
737 /// and return a reference providing modifiable access to this
738 /// timetable. This operation invalidates all iterators.
739 Timetable& operator=(const Timetable& rhs);
740
741 /// Add a transition to this timetable on the specified `date` at the
742 /// specified `time` having the specified `code`. If `time` is already
743 /// a transition point on `date`, replace the existing code with `code`.
744 /// The addition of a transition, but not the replacement of the code of
745 /// an existing transition, invalidates all iterators. The behavior is
746 /// undefined unless `24 > time.hour()`, `date` is within the valid
747 /// range of this timetable, and
748 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
749 void addTransition(const Date& date, const Time& time, int code);
750
751 /// Add a transition to this timetable at the specified `datetime`
752 /// having the specified `code`. If `datetime` is already a transition
753 /// point, replace the existing code with `code`. The addition of a
754 /// transition, but not the replacement of the code of an existing
755 /// transition, invalidates all iterators. The behavior is undefined
756 /// unless `24 > datetime.hour()`, `datetime.date()` is within the valid
757 /// range of this timetable, and
758 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
759 void addTransition(const Datetime& datetime, int code);
760
761 /// Add transitions to this timetable that occur at the specified
762 /// `time`, having the specified `code`, on all dates that are of the
763 /// specified `dayOfWeek` within the closed interval of dates from the
764 /// specified `firstDate` to the specified `lastDate`. For every date
765 /// on which this transition will occur, if `time` is already a
766 /// transition point, replace the existing code with `code`. The
767 /// addition of a transition, but not the replacement of the code of an
768 /// existing transition, invalidates all iterators. The behavior is
769 /// undefined unless `24 > time.hour()`, `firstDate <= lastDate`,
770 /// `firstDate` and `lastDate` are within the valid range of this
771 /// timetable, and `0 <= code || k_UNSET_TRANSITION_CODE == code`.
772 void addTransitions(const DayOfWeek::Enum& dayOfWeek,
773 const Time& time,
774 int code,
775 const Date& firstDate,
776 const Date& lastDate);
777
778 /// Remove all transitions from this timetable. The removal of a
779 /// transition invalidates all iterators.
781
782 /// If a transition occurs on the specified `date` at the specified
783 /// `time`, remove the transition from this timetable. Otherwise,
784 /// return without modifying this timetable. The removal of a
785 /// transition invalidates all iterators. The behavior is undefined
786 /// unless `24 > time.hour()` and `date` is within the valid range of
787 /// this timetable.
788 void removeTransition(const Date& date, const Time& time);
789
790 /// If a transition occurs at the specified `datetime`, remove the
791 /// transition from this timetable. Otherwise, return without modifying
792 /// this timetable. The removal of a transition invalidates all
793 /// iterators. The behavior is undefined unless `24 > datetime.hour()`
794 /// and `datetime.date()` is within the valid range of this timetable.
795 void removeTransition(const Datetime& datetime);
796
797 /// Remove all transitions from this timetable that occur on the
798 /// specified `date`. The removal of a transition invalidates all
799 /// iterators. The behavior is undefined unless `date` is within the
800 /// valid range of this timetable.
801 void removeTransitions(const Date& date);
802
803 /// Remove all transitions from this timetable that occur at the
804 /// specified `time` on all dates that are of the specified `dayOfWeek`
805 /// within the closed interval of dates from the specified `firstDate`
806 /// to the specified `lastDate`. The removal of a transition
807 /// invalidates all iterators. The behavior is undefined unless
808 /// `24 > time.hour()`, `firstDate <= lastDate`, and `firstDate` and
809 /// `lastDate` are within the valid range of this timetable.
810 void removeTransitions(const DayOfWeek::Enum& dayOfWeek,
811 const Time& time,
812 const Date& firstDate,
813 const Date& lastDate);
814
815 /// Reset this timetable to the default constructed (empty) state. All
816 /// associated iterators are invalidated.
817 void reset();
818
819 /// Set the transition code in effect at the start of this timetable to
820 /// the specified `code`. The behavior is undefined unless
821 /// `0 <= code || k_UNSET_TRANSITION_CODE == code`.
823
824 /// Set the range of this timetable using the specified `firstDate` and
825 /// `lastDate` as, respectively, the first date and the last date of the
826 /// timetable. Any transitions, and associated transition codes, that
827 /// are outside of the new range are removed. The removal of a
828 /// transition invalidates all iterators. The behavior is undefined
829 /// unless `firstDate <= lastDate`.
831
832 // Aspects
833
834 /// Efficiently exchange the value of this object with the value of the
835 /// specified `other` object. This method provides the no-throw
836 /// exception-safety guarantee. The behavior is undefined unless this
837 /// object was created with the same allocator as `other`.
838 void swap(Timetable& other);
839
840 // ACCESSORS
841
842 /// Return an iterator referring to the first transition in this
843 /// timetable, or the past-the-end iterator if this timetable is empty.
844 /// The iterator remains valid as long as this timetable exists, and the
845 /// number of transitions within this timetable does not change.
847
848 /// Return the past-the-end iterator for this timetable. The iterator
849 /// remains valid as long as this timetable exists, and the number of
850 /// transitions within this timetable does not change.
851 const_iterator end() const;
852
853 /// Return a `const` reference to the earliest date in the valid range
854 /// of this timetable. The behavior is undefined if this timetable does
855 /// not have a valid range (i.e., it is in the default constructed
856 /// (empty) state).
857 const Date& firstDate() const;
858
859 /// Return the transition code that is in effect at the start of this
860 /// timetable (see `setInitialTransitionCode`).
861 int initialTransitionCode() const;
862
863 /// Return `true` if the specified `date` is within the valid range of
864 /// this timetable, and `false` otherwise.
865 bool isInRange(const Date& date) const;
866
867 /// Return a `const` reference to the latest date in the valid range of
868 /// this timetable. The behavior is undefined if this timetable does
869 /// not have a valid range (i.e., it is in the default constructed
870 /// (empty) state).
871 const Date& lastDate() const;
872
873 /// Return the number of days in the valid range of this timetable,
874 /// which is defined to be 0 if this timetable is empty, and
875 /// `lastDate() - firstDate() + 1` otherwise.
876 int length() const;
877
878 /// Return the transition code associated with the latest transition
879 /// that occurs on or before the specified `date` and `time` in this
880 /// timetable. If this timetable has no such transition, return
881 /// `initialTransitionCode()`. The behavior is undefined unless
882 /// `24 > time.hour()` and `date` is within the valid range of this
883 /// timetable.
884 int transitionCodeInEffect(const Date& date, const Time& time) const;
885
886 /// Return the transition code associated with the latest transition
887 /// that occurs on or before the specified `datetime` in this timetable.
888 /// If this timetable has no such transition, return
889 /// `initialTransitionCode()`. The behavior is undefined unless
890 /// `24 > datetime.hour()` and `datetime.date()` is within the valid
891 /// range of this timetable.
892 int transitionCodeInEffect(const Datetime& datetime) const;
893
894 // Aspects
895
896 /// Return the allocator used by this object to supply memory.
898
899 /// Format this object to the specified output `stream` at the (absolute
900 /// value of) the optionally specified indentation `level` and return a
901 /// reference to the modifiable `stream`. If `level` is specified,
902 /// optionally specify `spacesPerLevel`, the number of spaces per
903 /// indentation level for this and all of its nested objects. If
904 /// `level` is negative, suppress indentation of the first line. If
905 /// `spacesPerLevel` is negative, format the entire output on one line,
906 /// suppressing all but the initial indentation (as governed by
907 /// `level`). If `stream` is not valid on entry, this operation has no
908 /// effect.
909 bsl::ostream& print(bsl::ostream& stream,
910 int level = 0,
911 int spacesPerLevel = 4) const;
912};
913
914// FREE OPERATORS
915
916/// Return `true` if the specified `lhs` and `rhs` timetables have the same
917/// value, and `false` otherwise. Two timetables have the same value if
918/// they have the same initial transition code, the same valid range (or are
919/// both empty), the same number of transitions, and each corresponding pair
920/// of transitions have the same value.
921bool operator==(const Timetable& lhs, const Timetable& rhs);
922
923/// Return `true` if the specified `lhs` and `rhs` timetables do not have
924/// the same value, and `false` otherwise. Two timetables do not have the
925/// same value if they do not have the same initial transition code, do not
926/// have the same valid range (and are not both empty), do not have the same
927/// number of transitions, or, for at least one corresponding pair of
928/// transitions, do not have the same value.
929bool operator!=(const Timetable& lhs, const Timetable& rhs);
930
931/// Write the value of the specified `timetable` to the specified output
932/// `stream`, and return a reference to the modifiable `stream`.
933bsl::ostream& operator<<(bsl::ostream& stream, const Timetable& timetable);
934
935// FREE FUNCTIONS
936
937/// Exchange the values of the specified `a` and `b` objects. This function
938/// provides the no-throw exception-safety guarantee if the two objects were
939/// created with the same allocator and the basic guarantee otherwise.
940void swap(Timetable& a, Timetable& b);
941
942// HASH SPECIALIZATIONS
943
944/// Pass the specified `object` to the specified `hashAlg`. This function
945/// integrates with the `bslh` modular hashing system and effectively
946/// provides a `bsl::hash` specialization for `Timetable`.
947template <class HASHALG>
948void hashAppend(HASHALG& hashAlg, const Timetable& object);
949
950 // =============================
951 // class Timetable_ConstIterator
952 // =============================
953
954/// Provide read-only, sequential access in increasing (chronological) order
955/// to the transitions in a `Timetable` object.
956///
957/// See @ref bdlt_timetable
959
960 // DATA
961 const Timetable *d_timetable_p; // pointer to the
962 // 'Timetable' into
963 // which this iterator
964 // references
965
966 bsl::size_t d_dayIndex; // index of the
967 // referenced daily
968 // timetable
969
970 bsl::size_t d_transitionIndex; // index of the
971 // referenced
972 // transition in the
973 // referenced daily
974 // timetable
975
976 mutable TimetableTransition_Ref d_ref; // cached value used
977 // for the return
978 // value of
979 // 'operator->()'
980
981 // FRIENDS
982 friend class Timetable;
983
988
989 private:
990 // PRIVATE CREATORS
991
992 /// Create a transition iterator for the specified `timetable` that
993 /// refers to the transition at the specified `transitionIndex` on the
994 /// day at the specified `dayIndex` in `timetable`.
995 Timetable_ConstIterator(const Timetable& timetable,
996 bsl::size_t dayIndex,
997 bsl::size_t transitionIndex);
998
999 public:
1000 // TYPES
1003
1004 /// The star operator returns a `TimetableTransition` *by* *value*.
1006
1007 // CREATORS
1008
1009 /// Create a default iterator. Note that the behavior of most methods
1010 /// is undefined when used on a default-constructed iterator.
1012
1013 /// Create an iterator having the value of the specified `original`
1014 /// iterator.
1016
1018 // Destroy this object.
1019
1020 // MANIPULATORS
1021
1022 /// Assign to this iterator the value of the specified `rhs` iterator,
1023 /// and return a reference providing modifiable access to this object.
1025
1026 /// Advance this iterator to refer to the next transition in the
1027 /// associated timetable, and return a reference providing modifiable
1028 /// access to this object. The behavior is undefined unless, on entry,
1029 /// this iterator references a valid transition.
1031
1032 /// Regress this iterator to refer to the previous transition in the
1033 /// associated timetable, and return a reference providing modifiable
1034 /// access to this object. The behavior is undefined unless, on entry,
1035 /// this iterator references a valid transition that is not the first
1036 /// transition of the associated timetable.
1038
1039 // ACCESSORS
1040
1041 /// Return, *by* *value*, a `TimetableTransition` object representing
1042 /// the transition referenced by this iterator. The behavior is
1043 /// undefined unless this iterator references a valid transition in the
1044 /// associated timetable.
1046
1047 /// Return a proxy to the transition referenced by this iterator. The
1048 /// behavior is undefined unless this iterator references a valid
1049 /// transition in the associated timetable.
1050 const TimetableTransition_Ref *operator->() const;
1051};
1052
1053// FREE OPERATORS
1054
1055/// Advance the specified `iterator` to refer to the next transition in the
1056/// referenced timetable, and return an iterator referring to the original
1057/// element (*before* the advancement). The behavior is undefined unless,
1058/// on entry, `iterator` references a valid transition.
1060
1061/// Regress the specified `iterator` to refer to the previous transition in
1062/// the referenced timetable, and return an iterator referring to the
1063/// original element (*before* the decrementation). The behavior is
1064/// undefined unless, on entry, `iterator` references a valid transition
1065/// that is not the first transition of the associated timetable.
1067
1068/// Return `true` if the specified `lhs` and `rhs` iterators have the same
1069/// value, and `false` otherwise. Two `Timetable_ConstIterator` iterators
1070/// have the same value if they refer to the same timetable and the same
1071/// transition.
1072bool operator==(const Timetable_ConstIterator& lhs,
1073 const Timetable_ConstIterator& rhs);
1074
1075/// Return `true` if the specified `lhs` and `rhs` iterators do not have the
1076/// same value, and `false` otherwise. Two `Timetable_ConstIterator`
1077/// iterators do not have the same value if they do not refer to the same
1078/// timetable, or do not refer to the same transition.
1079bool operator!=(const Timetable_ConstIterator& lhs,
1080 const Timetable_ConstIterator& rhs);
1081
1082// ============================================================================
1083// INLINE DEFINITIONS
1084// ============================================================================
1085
1086 // -------------------------
1087 // class TimetableTransition
1088 // -------------------------
1089
1090// PRIVATE CREATORS
1091inline
1092TimetableTransition::TimetableTransition()
1093: d_datetime(Date())
1094, d_code(k_UNSET_TRANSITION_CODE)
1095{
1096}
1097
1098inline
1099TimetableTransition::TimetableTransition(const Datetime& datetime, int code)
1100: d_datetime(datetime)
1101, d_code(code)
1102{
1103 BSLS_ASSERT(24 > datetime.hour());
1104
1105 BSLS_ASSERT(0 <= code || k_UNSET_TRANSITION_CODE == code);
1106}
1107
1108// CREATORS
1109inline
1110TimetableTransition::TimetableTransition(const TimetableTransition& original)
1111: d_datetime(original.d_datetime)
1112, d_code(original.d_code)
1113{
1114}
1115
1116// MANIPULATORS
1117inline
1119 const TimetableTransition& rhs)
1120{
1121 d_datetime = rhs.d_datetime;
1122 d_code = rhs.d_code;
1123
1124 return *this;
1125}
1126
1127// ACCESSORS
1128inline
1130{
1131 return d_datetime;
1132}
1133
1134inline
1136{
1137 return d_code;
1138}
1139
1140} // close package namespace
1141
1142// FREE OPERATORS
1143inline
1144bool bdlt::operator==(const TimetableTransition& lhs,
1145 const TimetableTransition& rhs)
1146{
1147 return lhs.datetime() == rhs.datetime() && lhs.code() == rhs.code();
1148}
1149
1150inline
1151bool bdlt::operator!=(const TimetableTransition& lhs,
1152 const TimetableTransition& rhs)
1153{
1154 return lhs.datetime() != rhs.datetime() || lhs.code() != rhs.code();
1155}
1156
1157inline
1158bool bdlt::operator<(const TimetableTransition& lhs,
1159 const TimetableTransition& rhs)
1160{
1161 return lhs.datetime() < rhs.datetime()
1162 || (lhs.datetime() == rhs.datetime() && lhs.code() < rhs.code());
1163}
1164
1165inline
1166bool bdlt::operator<(const TimetableTransition& lhs, const Datetime& rhs)
1167{
1168 BSLS_ASSERT(24 > rhs.hour());
1169
1170 return lhs.datetime() < rhs;
1171}
1172
1173inline
1174bool bdlt::operator<(const Datetime& lhs, const TimetableTransition& rhs)
1175{
1176 BSLS_ASSERT(24 > lhs.hour());
1177
1178 return lhs < rhs.datetime();
1179}
1180
1181// HASH SPECIALIZATIONS
1182template <class HASHALG>
1183inline
1184void bdlt::hashAppend(HASHALG& hashAlg, const TimetableTransition& object)
1185{
1186 using ::BloombergLP::bslh::hashAppend;
1187
1188 hashAppend(hashAlg, object.datetime());
1189 hashAppend(hashAlg, object.code());
1190}
1191
1192namespace bdlt {
1193
1194 // -----------------------------
1195 // class TimetableTransition_Ref
1196 // -----------------------------
1197
1198// PRIVATE CREATORS
1199inline
1200TimetableTransition_Ref::TimetableTransition_Ref()
1201: TimetableTransition()
1202{
1203}
1204
1205// CREATORS
1206inline
1207TimetableTransition_Ref::TimetableTransition_Ref(
1208 const TimetableTransition& transition)
1209: TimetableTransition(transition)
1210{
1211}
1212
1213inline
1214TimetableTransition_Ref::TimetableTransition_Ref(
1215 const TimetableTransition_Ref& original)
1216: TimetableTransition(original)
1217{
1218}
1219
1220// MANIPULATORS
1221inline
1222TimetableTransition_Ref& TimetableTransition_Ref::operator=(
1223 const TimetableTransition& rhs)
1224{
1225 d_datetime = rhs.d_datetime;
1226 d_code = rhs.d_code;
1227
1228 return *this;
1229}
1230
1231 // -------------------------------------
1232 // class Timetable_CompactableTransition
1233 // -------------------------------------
1234
1235// CREATORS
1236inline
1238: d_time(0)
1239, d_code(k_UNSET_TRANSITION_CODE)
1240{
1241}
1242
1243inline
1245 const Time& time,
1246 int code)
1247: d_time(time)
1248, d_code(code)
1249{
1250 BSLS_ASSERT(24 > time.hour());
1251
1253}
1254
1255inline
1257 const Timetable_CompactableTransition& original)
1258: d_time(original.d_time)
1259, d_code(original.d_code)
1260{
1261}
1262
1263// MANIPULATORS
1264inline
1267{
1268 d_time = rhs.d_time;
1269 d_code = rhs.d_code;
1270
1271 return *this;
1272}
1273
1274// ACCESSORS
1275inline
1277{
1278 return d_time;
1279}
1280
1281inline
1283{
1284 return d_code;
1285}
1286
1287} // close package namespace
1288
1289// FREE OPERATORS
1290inline
1291bool bdlt::operator==(const Timetable_CompactableTransition& lhs,
1292 const Timetable_CompactableTransition& rhs)
1293{
1294 return lhs.time() == rhs.time() && lhs.code() == rhs.code();
1295}
1296
1297inline
1298bool bdlt::operator!=(const Timetable_CompactableTransition& lhs,
1299 const Timetable_CompactableTransition& rhs)
1300{
1301 return lhs.time() != rhs.time() || lhs.code() != rhs.code();
1302}
1303
1304inline
1305bool bdlt::operator<(const Timetable_CompactableTransition& lhs,
1306 const Timetable_CompactableTransition& rhs)
1307{
1308 return lhs.time() < rhs.time()
1309 || (lhs.time() == rhs.time() && lhs.code() < rhs.code());
1310}
1311
1312inline
1313bool bdlt::operator<(const Timetable_CompactableTransition& lhs,
1314 const Time& rhs)
1315{
1316 BSLS_ASSERT(24 > rhs.hour());
1317
1318 return lhs.time() < rhs;
1319}
1320
1321inline
1322bool bdlt::operator<(const Time& lhs,
1323 const Timetable_CompactableTransition& rhs)
1324{
1325 BSLS_ASSERT(24 > lhs.hour());
1326
1327 return lhs < rhs.time();
1328}
1329
1330// HASH SPECIALIZATIONS
1331template <class HASHALG>
1332inline
1333void bdlt::hashAppend(HASHALG& hashAlg,
1334 const Timetable_CompactableTransition& object)
1335{
1336 using ::BloombergLP::bslh::hashAppend;
1337
1338 hashAppend(hashAlg, object.time());
1339 hashAppend(hashAlg, object.code());
1340}
1341
1342namespace bdlt {
1343
1344 // -------------------
1345 // class Timetable_Day
1346 // -------------------
1347
1348// CREATORS
1349inline
1351: d_initialTransitionCode(k_UNSET_TRANSITION_CODE)
1352, d_transitions(basicAllocator)
1353{
1354}
1355
1356inline
1358 bslma::Allocator *basicAllocator)
1359: d_initialTransitionCode(original.d_initialTransitionCode)
1360, d_transitions(original.d_transitions, basicAllocator)
1361{
1362}
1363
1364// MANIPULATORS
1365inline
1367{
1368 d_initialTransitionCode = rhs.d_initialTransitionCode;
1369 d_transitions = rhs.d_transitions;
1370
1371 return *this;
1372}
1373
1374inline
1376{
1377 int code = finalTransitionCode();
1378
1379 d_transitions.clear();
1380
1381 return code != d_initialTransitionCode;
1382}
1383
1384inline
1386{
1387 BSLS_ASSERT(0 <= code || k_UNSET_TRANSITION_CODE == code);
1388
1389 bool rv = d_initialTransitionCode != code && d_transitions.empty();
1390
1391 d_initialTransitionCode = code;
1392
1393 return rv;
1394}
1395
1396// ACCESSORS
1397inline
1399{
1401 d_transitions.rbegin();
1402
1403 return iter != d_transitions.rend()
1404 ? iter->d_code
1405 : d_initialTransitionCode;
1406}
1407
1408inline
1410{
1411 return d_initialTransitionCode;
1412}
1413
1414inline
1415bsl::size_t Timetable_Day::size() const
1416{
1417 return d_transitions.size();
1418}
1419
1420} // close package namespace
1421
1422// FREE OPERATORS
1423inline
1424bool bdlt::operator==(const Timetable_Day& lhs, const Timetable_Day& rhs)
1425{
1426 return lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1427 && lhs.d_transitions == rhs.d_transitions;
1428}
1429
1430inline
1431bool bdlt::operator!=(const Timetable_Day& lhs, const Timetable_Day& rhs)
1432{
1433 return lhs.d_initialTransitionCode != rhs.d_initialTransitionCode
1434 || lhs.d_transitions != rhs.d_transitions;
1435}
1436
1437inline
1438bool bdlt::operator<(const Timetable_Day& lhs, const Timetable_Day& rhs)
1439{
1440 return lhs.d_initialTransitionCode < rhs.d_initialTransitionCode
1441 || ( lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1442 && lhs.d_transitions < rhs.d_transitions);
1443}
1444
1445// HASH SPECIALIZATIONS
1446template <class HASHALG>
1447inline
1448void bdlt::hashAppend(HASHALG& hashAlg, const Timetable_Day& object)
1449{
1450 using ::BloombergLP::bslh::hashAppend;
1451
1452 hashAppend(hashAlg, object.d_initialTransitionCode);
1453 hashAppend(hashAlg, object.d_transitions);
1454}
1455
1456namespace bdlt {
1457
1458 // ---------------
1459 // class Timetable
1460 // ---------------
1461
1462// MANIPULATORS
1463inline
1465{
1466 Timetable(rhs, allocator()).swap(*this);
1467
1468 return *this;
1469}
1470
1471inline
1472void Timetable::addTransition(const Datetime& datetime, int code)
1473{
1474 addTransition(datetime.date(), datetime.time(), code);
1475}
1476
1477inline
1479{
1480 Date firstDate = d_firstDate;
1481 Date lastDate = d_lastDate;
1482
1483 d_firstDate = Date(9999, 12, 31);
1484 d_lastDate = Date( 1, 1, 1);
1485
1486 d_timetable.removeAll();
1487
1489}
1490
1491inline
1493{
1494 removeTransition(datetime.date(), datetime.time());
1495}
1496
1497inline
1499{
1500 d_initialTransitionCode = k_UNSET_TRANSITION_CODE;
1501
1502 d_firstDate = Date(9999, 12, 31);
1503 d_lastDate = Date( 1, 1, 1);
1504
1505 d_timetable.removeAll();
1506}
1507
1508 // Aspects
1509
1510inline
1512{
1513 // Member 'swap' is undefined for objects with non-equal allocators.
1514
1515 BSLS_ASSERT(allocator() == other.allocator());
1516
1517 bslalg::SwapUtil::swap(&d_initialTransitionCode,
1518 &other.d_initialTransitionCode);
1519
1520 bslalg::SwapUtil::swap(&d_firstDate, &other.d_firstDate);
1521 bslalg::SwapUtil::swap(&d_lastDate, &other.d_lastDate);
1522 bslalg::SwapUtil::swap(&d_timetable, &other.d_timetable);
1523}
1524
1525// ACCESSORS
1526inline
1528{
1529 return Timetable_ConstIterator(*this, d_timetable.length(), 0);
1530}
1531
1532inline
1534{
1535 BSLS_ASSERT(0 < length());
1536
1537 return d_firstDate;
1538}
1539
1540inline
1542{
1543 return d_initialTransitionCode;
1544}
1545
1546inline
1547bool Timetable::isInRange(const Date& date) const
1548{
1549 return date >= d_firstDate && date <= d_lastDate;
1550}
1551
1552inline
1554{
1555 BSLS_ASSERT(0 < length());
1556
1557 return d_lastDate;
1558}
1559
1560inline
1562{
1563 return d_firstDate <= d_lastDate ? d_lastDate - d_firstDate + 1 : 0;
1564}
1565
1566inline
1567int Timetable::transitionCodeInEffect(const Date& date, const Time& time) const
1568{
1569 BSLS_ASSERT(24 > time.hour());
1570 BSLS_ASSERT(isInRange(date));
1571
1572 bsl::size_t index = date - d_firstDate;
1573 const Timetable_Day& daily = d_timetable[index];
1574
1575 return daily.transitionCodeInEffect(time);
1576}
1577
1578inline
1580{
1581 return transitionCodeInEffect(datetime.date(), datetime.time());
1582}
1583
1584 // Aspects
1585
1586inline
1588{
1589 return d_timetable.allocator();
1590}
1591
1592} // close package namespace
1593
1594// FREE OPERATORS
1595inline
1596bool bdlt::operator==(const Timetable& lhs, const Timetable& rhs)
1597{
1598 return lhs.d_initialTransitionCode == rhs.d_initialTransitionCode
1599 && lhs.d_firstDate == rhs.d_firstDate
1600 && lhs.d_lastDate == rhs.d_lastDate
1601 && lhs.d_timetable == rhs.d_timetable;
1602}
1603
1604inline
1605bool bdlt::operator!=(const Timetable& lhs, const Timetable& rhs)
1606{
1607 return lhs.d_initialTransitionCode != rhs.d_initialTransitionCode
1608 || lhs.d_firstDate != rhs.d_firstDate
1609 || lhs.d_lastDate != rhs.d_lastDate
1610 || lhs.d_timetable != rhs.d_timetable;
1611}
1612
1613inline
1614bsl::ostream& bdlt::operator<<(bsl::ostream& stream,
1615 const Timetable& timetable)
1616{
1617 return timetable.print(stream, 0, -1);
1618}
1619
1620// FREE FUNCTIONS
1621inline
1622void bdlt::swap(Timetable& a, Timetable& b)
1623{
1624 if (a.allocator() == b.allocator()) {
1625 a.swap(b);
1626
1627 return; // RETURN
1628 }
1629
1630 Timetable futureA(b, a.allocator());
1631 Timetable futureB(a, b.allocator());
1632
1633 futureA.swap(a);
1634 futureB.swap(b);
1635}
1636
1637// HASH SPECIALIZATIONS
1638template <class HASHALG>
1639inline
1640void bdlt::hashAppend(HASHALG& hashAlg, const Timetable& object)
1641{
1642 using ::BloombergLP::bslh::hashAppend;
1643
1644 hashAppend(hashAlg, object.d_firstDate);
1645 hashAppend(hashAlg, object.d_lastDate);
1646 hashAppend(hashAlg, object.d_initialTransitionCode);
1647 hashAppend(hashAlg, object.d_timetable);
1648}
1649
1650namespace bdlt {
1651
1652 // -----------------------------
1653 // class Timetable_ConstIterator
1654 // -----------------------------
1655
1656// PRIVATE CREATORS
1657inline
1659 const Timetable& timetable,
1660 bsl::size_t dayIndex,
1661 bsl::size_t transitionIndex)
1662: d_timetable_p(&timetable)
1663, d_dayIndex(dayIndex)
1664, d_transitionIndex(transitionIndex)
1665{
1666}
1667
1668// CREATORS
1669inline
1671: d_timetable_p(0)
1672, d_dayIndex(0)
1673, d_transitionIndex(0)
1674{
1675}
1676
1677inline
1679 const Timetable_ConstIterator& original)
1680: d_timetable_p(original.d_timetable_p)
1681, d_dayIndex(original.d_dayIndex)
1682, d_transitionIndex(original.d_transitionIndex)
1683{
1684}
1685
1686// MANIPULATORS
1687inline
1690{
1691 d_timetable_p = rhs.d_timetable_p;
1692 d_dayIndex = rhs.d_dayIndex;
1693 d_transitionIndex = rhs.d_transitionIndex;
1694
1695 return *this;
1696}
1697
1698// ACCESSORS
1699inline
1701{
1702 BSLS_ASSERT(d_timetable_p);
1703 BSLS_ASSERT(d_dayIndex
1704 < static_cast<bsl::size_t>(d_timetable_p->length()));
1705 BSLS_ASSERT(d_transitionIndex
1706 < d_timetable_p->d_timetable[d_dayIndex].size());
1707
1708 const Timetable_CompactableTransition& transition =
1709 d_timetable_p->d_timetable[d_dayIndex].d_transitions[
1710 d_transitionIndex];
1711 return TimetableTransition(
1712 Datetime(d_timetable_p->firstDate() + static_cast<int>(d_dayIndex),
1713 transition.time()),
1714 transition.code());
1715}
1716
1717inline
1719{
1720 BSLS_ASSERT(d_timetable_p);
1721 BSLS_ASSERT(d_dayIndex
1722 < static_cast<bsl::size_t>(d_timetable_p->length()));
1723
1724 d_ref = this->operator*();
1725 return &d_ref;
1726}
1727
1728} // close package namespace
1729
1730// FREE OPERATORS
1731inline
1733 Timetable_ConstIterator& iterator,
1734 int)
1735{
1736 const Timetable_ConstIterator curr = iterator;
1737 ++iterator;
1738 return curr;
1739}
1740
1741inline
1743 Timetable_ConstIterator& iterator,
1744 int)
1745{
1746 const Timetable_ConstIterator curr = iterator;
1747 --iterator;
1748 return curr;
1749}
1750
1751inline
1752bool bdlt::operator==(const Timetable_ConstIterator& lhs,
1753 const Timetable_ConstIterator& rhs)
1754{
1755 return lhs.d_timetable_p == rhs.d_timetable_p
1756 && lhs.d_dayIndex == rhs.d_dayIndex
1757 && lhs.d_transitionIndex == rhs.d_transitionIndex;
1758}
1759
1760inline
1761bool bdlt::operator!=(const Timetable_ConstIterator& lhs,
1762 const Timetable_ConstIterator& rhs)
1763{
1764 return lhs.d_timetable_p != rhs.d_timetable_p
1765 || lhs.d_dayIndex != rhs.d_dayIndex
1766 || lhs.d_transitionIndex != rhs.d_transitionIndex;
1767}
1768
1769
1770
1771// TRAITS
1772
1773
1774namespace bslma {
1775
1776template <>
1777struct UsesBslmaAllocator<bdlt::Timetable_Day> : bsl::true_type {};
1778
1779template <>
1781
1782} // close namespace bslma
1783
1784
1785#endif
1786
1787// ----------------------------------------------------------------------------
1788// Copyright 2018 Bloomberg Finance L.P.
1789//
1790// Licensed under the Apache License, Version 2.0 (the "License");
1791// you may not use this file except in compliance with the License.
1792// You may obtain a copy of the License at
1793//
1794// http://www.apache.org/licenses/LICENSE-2.0
1795//
1796// Unless required by applicable law or agreed to in writing, software
1797// distributed under the License is distributed on an "AS IS" BASIS,
1798// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1799// See the License for the specific language governing permissions and
1800// limitations under the License.
1801// ----------------------------- END-OF-FILE ----------------------------------
1802
1803/** @} */
1804/** @} */
1805/** @} */
Definition bdlc_compactedarray.h:670
Definition bdlt_date.h:294
Definition bdlt_datetime.h:331
Date date() const
Return the value of the "date" part of this object.
Definition bdlt_datetime.h:2164
Time time() const
Return the value of the "time" part of this object.
Definition bdlt_datetime.h:2275
Definition bdlt_time.h:196
int hour() const
Return the value of the hour attribute of this time object.
Definition bdlt_time.h:898
Definition bdlt_timetable.h:336
Definition bdlt_timetable.h:216
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:240
TimetableTransition & operator=(const TimetableTransition &rhs)
Definition bdlt_timetable.h:1118
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:1135
const Datetime & datetime() const
Return the datetime of this transition.
Definition bdlt_timetable.h:1129
~TimetableTransition()=default
Destroy this object.
Definition bdlt_timetable.h:381
int code() const
Return the code of this compactable transition.
Definition bdlt_timetable.h:1282
const Time & time() const
Return the time of this compactable transition.
Definition bdlt_timetable.h:1276
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Timetable_CompactableTransition()
Definition bdlt_timetable.h:1237
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:393
Timetable_CompactableTransition & operator=(const Timetable_CompactableTransition &rhs)
Definition bdlt_timetable.h:1265
Definition bdlt_timetable.h:958
const TimetableTransition_Ref * operator->() const
Definition bdlt_timetable.h:1718
Timetable_ConstIterator & operator=(const Timetable_ConstIterator &rhs)
Definition bdlt_timetable.h:1689
friend bool operator==(const Timetable_ConstIterator &, const Timetable_ConstIterator &)
Timetable_ConstIterator()
Definition bdlt_timetable.h:1670
TimetableTransition operator*() const
Definition bdlt_timetable.h:1700
Timetable_ConstIterator & operator--()
TimetableTransition value_type
Definition bdlt_timetable.h:1001
TimetableTransition_Ref * pointer
Definition bdlt_timetable.h:1002
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:1005
Definition bdlt_timetable.h:511
int initialTransitionCode() const
Definition bdlt_timetable.h:1409
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:1375
bool setInitialTransitionCode(int code)
Definition bdlt_timetable.h:1385
~Timetable_Day()=default
bool addTransition(const Time &time, int code)
Timetable_Day & operator=(const Timetable_Day &rhs)
Definition bdlt_timetable.h:1366
bool removeTransition(const Time &time)
int finalTransitionCode() const
Definition bdlt_timetable.h:1398
bsl::size_t size() const
Return the number of transitions in this daily timetable.
Definition bdlt_timetable.h:1415
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:534
Timetable_Day(bslma::Allocator *basicAllocator=0)
Definition bdlt_timetable.h:1350
friend bool operator<(const Timetable_Day &, const Timetable_Day &)
friend bool operator==(const Timetable_Day &, const Timetable_Day &)
Definition bdlt_timetable.h:667
int transitionCodeInEffect(const Date &date, const Time &time) const
Definition bdlt_timetable.h:1567
~Timetable()=default
Timetable_ConstIterator const_iterator
Definition bdlt_timetable.h:698
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:1587
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:1511
friend class Timetable_ConstIterator
Definition bdlt_timetable.h:682
int initialTransitionCode() const
Definition bdlt_timetable.h:1541
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:1547
const_iterator end() const
Definition bdlt_timetable.h:1527
void reset()
Definition bdlt_timetable.h:1498
friend bool operator!=(const Timetable &, const Timetable &)
void removeTransitions(const Date &date)
const Date & lastDate() const
Definition bdlt_timetable.h:1553
void removeTransition(const Date &date, const Time &time)
@ k_UNSET_TRANSITION_CODE
Definition bdlt_timetable.h:692
const Date & firstDate() const
Definition bdlt_timetable.h:1533
int length() const
Definition bdlt_timetable.h:1561
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:1478
Timetable & operator=(const Timetable &rhs)
Definition bdlt_timetable.h:1464
Definition bslstl_vector.h:1025
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_vector.h:1060
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_IDENT(str)
Definition bsls_ident.h:195
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
Definition bbldc_basicisma30360.h:112
bool operator<(const Date &lhs, const Date &rhs)
Calendar_BusinessDayConstIter operator++(Calendar_BusinessDayConstIter &iterator, int)
Definition bdlt_calendar.h:2156
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:2165
Definition balxml_encoderoptions.h:68
Enum
Enumerated day-of-week values.
Definition bdlt_dayofweek.h:123
Definition bslma_usesbslmaallocator.h:343