BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsltf_testvaluesarray.h
Go to the documentation of this file.
1/// @file bsltf_testvaluesarray.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_testvaluesarray.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_TESTVALUESARRAY
9#define INCLUDED_BSLTF_TESTVALUESARRAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_testvaluesarray bsltf_testvaluesarray
15/// @brief Provide a container for values used for testing.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_testvaluesarray
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_testvaluesarray-purpose"> Purpose</a>
25/// * <a href="#bsltf_testvaluesarray-classes"> Classes </a>
26/// * <a href="#bsltf_testvaluesarray-description"> Description </a>
27/// * <a href="#bsltf_testvaluesarray-iterator"> Iterator </a>
28/// * <a href="#bsltf_testvaluesarray-thread-safety"> Thread Safety </a>
29/// * <a href="#bsltf_testvaluesarray-c-20-ranges"> C++20 Ranges </a>
30/// * <a href="#bsltf_testvaluesarray-usage"> Usage </a>
31/// * <a href="#bsltf_testvaluesarray-example-1-testing-a-simple-template-function"> Example 1: Testing a Simple Template Function </a>
32///
33/// # Purpose {#bsltf_testvaluesarray-purpose}
34/// Provide a container for values used for testing.
35///
36/// # Classes {#bsltf_testvaluesarray-classes}
37///
38/// - bsltf::TestValuesArray: container for values used for testing
39/// - bsltf::TestValuesArrayIterator: iterator for the container
40/// - bsltf::TestValuesArraySentinel: sentinel for the container
41///
42/// @see bsltf_templatetestfacility
43///
44/// # Description {#bsltf_testvaluesarray-description}
45/// This component defines a class `bsltf::TestValuesArray`
46/// providing a uniform interface for creating and accessing a sequence of test
47/// values of a type that has a copy constructor, and may or may not have a
48/// default constructor.
49///
50/// This component also defines an iterator class
51/// `bsltf::TestValuesArrayIterator` providing access to elements in a
52/// `TestValuesArray` object. `TestValuesArrayIterator` is designed to
53/// satisfies the minimal requirement of an input iterator as defined by the
54/// C++11 standard [24.2.3]. It uses the `BSLS_ASSERT` macro to detect
55/// undefined behavior.
56///
57/// The sequence described by this container is an input-range, that may be
58/// traversed exactly once. Once an iterator is incremented, any other iterator
59/// at the same position in the sequence is invalidated. The `TestValuesArray`
60/// object provides a `resetIterators` method that restores the ability to
61/// iterate the container.
62///
63/// ## Iterator {#bsltf_testvaluesarray-iterator}
64///
65///
66/// The requirements of the input iterators as defined by the C++11 standard may
67/// not be as tight as the users of the input iterators expected. Incorrect
68/// assumptions about the properties of the input iterator may result in
69/// undefined behavior. `TestValuesArrayIterator` is designed to detect
70/// possible incorrect usages. Specifically, `TestValuesArrayIterator` put
71/// restriction on when it can be dereferenced or compared. A
72/// `TestValuesArrayIterator` is considered to be *dereferenceable* if it
73/// satisfies all of the following:
74///
75/// 1. The iterator refers to a valid element (not `end`).
76/// 2. The iterator has not been dereferenced. (*)
77/// 3. The iterator is not a copy of another iterator of which `operator++`
78/// have been invoked. (see [table 107] of the C++11 standard)
79///
80/// *note: An input iterator may not be dereferenced more than once is a common
81/// requirement of a container method that takes input iterators as arguments.
82/// Other standard algorithms may allow the iterator to be dereferenced more
83/// than once, in which case, `TestValuesArrayIterator` is not suitable to be
84/// used to with those algorithms.
85///
86/// `TestValuesArrayIterator` is comparable if the iterator is not a copy of
87/// another iterator of which `operator++` have been invoked.
88///
89/// ## Thread Safety {#bsltf_testvaluesarray-thread-safety}
90///
91///
92/// This component is *not* thread-safe, by any definition of the term, and
93/// should not be used in test scenarios concerned with concurrent code.
94///
95/// ## C++20 Ranges {#bsltf_testvaluesarray-c-20-ranges}
96///
97///
98/// `TestValueArray`, `TestValueArrayIterator`, and `TestValueArraySentinel`
99/// collectively meet the requirements of the Standard
100/// "container-compatible-range" concept. Template parameter `USE_SENTINEL`
101/// (default `false`) determines whether the type returned by the `end` method
102/// is TestValueArrayIterator` or `TestValuesArraySentinel`, a class that is
103/// not a fully-functional iterator (e.g., it cannot be dereferenced) that can
104/// also define the end of a range.
105///
106/// ## Usage {#bsltf_testvaluesarray-usage}
107///
108///
109/// This section illustrates intended use of this component.
110///
111/// ### Example 1: Testing a Simple Template Function {#bsltf_testvaluesarray-example-1-testing-a-simple-template-function}
112///
113///
114/// Suppose that we have a function that we would like to test. This function
115/// take in a range defined by two input iterators and returns the largest value
116/// in that range.
117///
118/// First, we define the function we would like to test:
119/// @code
120/// template <class VALUE, class INPUT_ITERATOR>
121/// VALUE myMaxValue(INPUT_ITERATOR first, INPUT_ITERATOR last)
122/// // Return the largest value referred to by the iterators in the range
123/// // beginning at the specified 'first' and up to, but not including, the
124/// // specified 'last'. The behavior is undefined unless [first, last)
125/// // specifies a valid range and 'first != last'.
126/// {
127/// assert(first != last);
128///
129/// VALUE largestValue(*first);
130/// ++first;
131/// for(;first != last; ++first) {
132/// // Store in temporary variable to avoid dereferencing twice.
133///
134/// const VALUE& temp = *first;
135/// if (largestValue < temp) {
136/// largestValue = temp;
137/// }
138/// }
139/// return largestValue;
140/// }
141/// @endcode
142/// Next, we implement a test function `runTest` that allows the function to be
143/// tested with different types:
144/// @code
145/// template <class VALUE>
146/// void runTest()
147/// // Test driver.
148/// {
149/// @endcode
150/// Then, we define a set of test values and expected results:
151/// @code
152/// struct {
153/// const char *d_spec;
154/// const char d_result;
155/// } DATA[] = {
156/// { "A", 'A' },
157/// { "ABC", 'C' },
158/// { "ADCB", 'D' },
159/// { "EDCBA", 'E' }
160/// };
161/// const size_t NUM_DATA = sizeof DATA / sizeof *DATA;
162/// @endcode
163/// Now, for each set of test values, verify that the function return the
164/// expected result.
165/// @code
166/// for (size_t i = 0; i < NUM_DATA; ++i) {
167/// const char *const SPEC = DATA[i].d_spec;
168/// const VALUE EXP =
169/// bsltf::TemplateTestFacility::create<VALUE>(DATA[i].d_result);
170///
171/// bsltf::TestValuesArray<VALUE> values(SPEC);
172/// assert(EXP == myMaxValue<VALUE>(values.begin(), values.end()));
173/// }
174/// }
175/// @endcode
176/// Finally, we invoke the test function to verify our function is implemented
177/// correctly. The test function to run without triggering the `assert`
178/// statement:
179/// @code
180/// runTest<char>();
181/// @endcode
182/// @}
183/** @} */
184/** @} */
185
186/** @addtogroup bsl
187 * @{
188 */
189/** @addtogroup bsltf
190 * @{
191 */
192/** @addtogroup bsltf_testvaluesarray
193 * @{
194 */
195
196#include <bslscm_version.h>
197
199
200#include <bslmf_conditional.h> // `bsl::conditional`
201#include <bslmf_typeidentity.h>
202
203#include <bslma_bslallocator.h>
204
205#include <bsls_alignmentutil.h>
206#include <bsls_libraryfeatures.h>
207
208#include <iterator>
209#include <stddef.h>
210#include <string.h>
211
212#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
213#include <bsls_nativestd.h>
214#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
215
216
217
218namespace bsltf {
219
220template <class VALUE, class ALLOCATOR>
221struct TestValuesArray_DefaultConverter;
222
223template <class VALUE>
224class TestValuesArray_PostIncrementPtr;
225
226template <class VALUE>
227class TestValuesArraySentinel;
228
229 // =============================
230 // class TestValuesArrayIterator
231 // =============================
232
233/// This class provide a STL-conforming input iterator over values used for
234/// testing (see section [24.2.3 input.iterators] of the C++11 standard. A
235/// `TestValuesArrayIterator` provide access to elements of parameterized
236/// type `VALUE`. An iterator is considered dereferenceable all of the
237/// following are satisfied:
238/// 1. The iterator refers to a valid element (not `end`).
239/// 2. The iterator has not been dereferenced.
240/// 3. The iterator is not a copy of another iterator of which `operator++`
241/// have been invoked.
242/// An iterator is comparable if the iterator is not a copy of another
243/// iterator of which `operator++` have been invoked.
244///
245/// This class is *not* thread-safe: different iterator objects manipulate
246/// shared state without synchronization. This is rarely a concern for the
247/// test scenarios supported by this component.
248///
249/// See @ref bsltf_testvaluesarray
250template <class VALUE>
252
253 // DATA
254 const VALUE *d_data_p; // pointer to array of values (held,
255 // not owned)
256
257 const VALUE *d_end_p; // end pointer (held, not owned)
258 // -- for defensive checks only
259
260 bool *d_dereferenceable_p; // indicate if dereferenceable (held,
261 // not owned)
262
263 bool *d_isValid_p; // indicate not yet invalidated (held,
264 // not owned)
265
266 private:
267 // FRIENDS
268
269 template <class OTHER_VALUE>
272
273 template <class OTHER_VALUE>
276
277 template <class OTHER_VALUE>
280
281 template <class OTHER_VALUE>
284
285 template <class OTHER_VALUE>
288
289 template <class OTHER_VALUE>
292 public:
293 // TYPES
294 typedef std::input_iterator_tag iterator_category;
295 typedef VALUE value_type;
296 typedef ptrdiff_t difference_type;
297 typedef const VALUE *pointer;
298
299 /// Standard iterator defined types [24.4.2].
300 typedef const VALUE& reference;
301
302 public:
303 // CREATORS
304
305 /// Create a null-initialized iterator.
306 /// \note Note that this iterator can be
307 /// used in the sentinel role for a C++20 standard range. Also note that
308 /// sentinel default-constructibility is a requirement of the Standard
309 /// container-convertible-range concept.
311
312 /// Create an iterator referring to the specified `object` for a
313 /// container with the specified `end`, with two arrays of boolean
314 /// referred to by the specified `dereferenceable` and `isValid` to
315 /// indicate whether this iterator and its subsequent values until
316 /// `end` is allowed to be dereferenced and is not yet invalidated
317 /// respectively.
318 TestValuesArrayIterator(const VALUE *object,
319 const VALUE *end,
320 bool *dereferenceable,
321 bool *isValid);
322
323 /// Create an iterator having the same value as the specified `original` object.
324 ///
325 /// \pre The behavior is undefined unless `original` is valid.
327
328 // MANIPULATORS
329
330 /// Assign to this object the value of the specified `other` object.
331 ///
332 /// \pre The behavior is undefined unless `other` is valid.
334
335 /// Move this iterator to the next element in the container. Any copies
336 /// of this iterator are no longer dereferenceable or comparable.
337 ///
338 /// \pre The behavior is undefined unless this iterator refers to a valid value
339 /// in the container.
341
342 /// Move this iterator to the next element in the container, and return
343 /// an object that can be dereferenced to refer to the same object that
344 /// this iterator initially points to. Any copies of this iterator are
345 /// no longer dereferenceable or comparable.
346 ///
347 /// \pre The behavior is undefined unless this iterator refers to a valid value in the container.
349
350 // ACCESSORS
351
352 /// Return the value referred to by this object. This object is no
353 /// longer dereferenceable after a call to this function.
354 ///
355 /// \pre The behavior is undefined unless this iterator is dereferenceable.
356 const VALUE& operator *() const;
357
358 /// Return the address of the element (of the template parameter
359 /// `VALUE`) at which this iterator is positioned.
360 ///
361 /// \pre The behavior is undefined unless this iterator is dereferenceable.
362 const VALUE *operator->() const;
363
364 /// Return the position (address) referenced by this iterator.
365 const VALUE *address() const;
366};
367
368/// Return `true` if the specified `lhs` and the specified `rhs` refer to
369/// the same element, and `false` otherwise.
370///
371/// \pre The behavior is undefined unless `lhs` and `rhs` are comparable.
372template <class VALUE>
373bool operator==(const TestValuesArrayIterator<VALUE>& lhs,
375
376/// Return `true` if the specified `lhs` and the specified `rhs` do *not*
377/// refer to the same element, and `false` otherwise.
378///
379/// \pre The behavior is undefined unless `lhs` and `rhs` are comparable.
380template <class VALUE>
381bool operator!=(const TestValuesArrayIterator<VALUE>& lhs,
383
384 // =============================
385 // class TestValuesArraySentinel
386 // =============================
387
388template <class VALUE>
390
391 const VALUE *d_end_p;
392
393 // FRIENDS
394 template <class OTHER_VALUE>
397
398 template <class OTHER_VALUE>
401
402 template <class OTHER_VALUE>
405
406 template <class OTHER_VALUE>
409
410 public:
411
412 // CREATORS
413
414 /// Create a sentinel object that "refers" to `nullptr`.
415 /// \note Note that a
416 /// default constructor is required by the `bsl::sentinel_for` concept.
418
419 /// Create a sentinel object that refers the specified `end` position (address).
420 ///
421 /// \note Note that no facility is provided to change the position of
422 /// a sentinel object.
423 TestValuesArraySentinel(const VALUE *end);
424
425 // ACCESSORS
426
427 /// Return the position (address) referenced by this sentinel.
428 const VALUE *address() const;
429};
430
431/// Return `true` if the specified `lhs` and the specified `rhs` refer to
432/// the same element, and `false` otherwise.
433///
434/// \pre The behavior is undefined unless `lhs` and `rhs` are comparable.
435template <class VALUE>
436bool operator==(const TestValuesArrayIterator<VALUE>& lhs,
438template <class VALUE>
439bool operator==(const TestValuesArraySentinel<VALUE>& lhs,
441
442/// Return `true` if the specified `lhs` and the specified `rhs` do *not*
443/// refer to the same element, and `false` otherwise.
444///
445/// \pre The behavior is undefined unless `lhs` and `rhs` are comparable.
446template <class VALUE>
447bool operator!=(const TestValuesArrayIterator<VALUE>& lhs,
449template <class VALUE>
450bool operator!=(const TestValuesArraySentinel<VALUE>& lhs,
452
453 // =====================
454 // class TestValuesArray
455 // =====================
456
457/// This class provides a container to store values of the (template
458/// parameter) type `VALUE`, and also provides the iterators to access the
459/// values. The iterators are designed to conform to a standard input
460/// iterator, and report any misuse of the iterator.
461///
462/// See @ref bsltf_testvaluesarray
463template <class VALUE,
464 class ALLOCATOR = bsl::allocator<VALUE>,
466 bool USE_SENTINEL = false>
468
469 private:
470 // PRIVATE TYPES
472 rebind_traits<bsls::AlignmentUtil::MaxAlignedType>
473 AllocatorTraits;
474 typedef typename AllocatorTraits::allocator_type AllocatorType;
475 typedef typename AllocatorTraits::size_type size_type;
476
477 // DATA
478 ALLOCATOR d_allocator; // allocator (held, not owned)
479
480 VALUE *d_data_p; // pointer to memory storing the values
481 // (owned)
482
483 size_t d_size; // number of elements in this container
484
485 bool *d_dereferenceable_p; // pointer to an array to indicate if
486 // value is dereferenceable (owned)
487
488 bool *d_validIterator_p; // pointer to an array to indicate if
489 // value is comparable (owned)
490
491 private:
492 // NOT IMPLEMENTED
493 TestValuesArray(const TestValuesArray& ); // = delete
494 TestValuesArray& operator=(const TestValuesArray& ); // = delete
495
496 // PRIVATE MANIPULATORS
497
498 /// Initialize this container, using the specified `spec` to populate
499 /// container with test values.
500 void initialize(const char *spec);
501
502 public:
503 // TYPES
504
505 /// Iterator/Sentinel for this container.
506
511 typedef typename bsl::conditional<USE_SENTINEL,
512 sentinel,
514 typedef typename bsl::conditional<USE_SENTINEL,
517
518 // PRIVATE MANIPULATORS
519
522
525
526 public:
527 // CREATORS
528
529 /// Create a `TestValuesArray` object. Optionally, specify `spec` to
530 /// indicate the values this object should contain, where the values are
531 /// created by invoking the `bsltf::TemplateTestFacility::create` method
532 /// on each character of `spec`. If no `spec` is supplied, the object
533 /// will contain 52 distinct values of the (template parameter) type
534 /// `VALUE`. Optionally, specify `basicAllocator` used to supply
535 /// memory. If no allocator is supplied, a `bslma::MallocFree`
536 /// allocator is used to supply memory.
537 explicit TestValuesArray();
538 explicit TestValuesArray(ALLOCATOR basicAllocator);
539 explicit TestValuesArray(const char *spec);
540 explicit TestValuesArray(const char *spec, ALLOCATOR basicAllocator);
541
542 /// Destroy this container and all contained elements.
544
545 // MANIPULATORS
546
547 /// Return an iterator providing non-modifiable access to the first
548 /// `VALUE` object in the sequence of `VALUE` objects maintained by this
549 /// container, or the `end` iterator if this container is empty.
550 iterator begin();
551
552 /// Return an iterator (sentinel) referencing to one position past the end
553 /// of the sequence of `VALUE` objects maintained by this container.
554 /// The return type is determined by (template) parameter `USE_SENTINEL`
555 /// and `USE_SENTINEL` defaults to false` (i.e., `end()` returns an
556 /// `iterator`).
558
559 /// Return an iterator to the element at the specified `position`.
560 ///
561 /// \pre The behavior is undefined unless `position <= size()`.
562 iterator index(size_t position);
563
564 /// Make all iterators dereferenceable and comparable again.
565 void resetIterators();
566
567 // ACCESSORS
568
569 /// Return an iterator providing non-modifiable access to the first
570 /// `VALUE` object in the sequence of `VALUE` objects maintained by this
571 /// container, or the `end` iterator if this container is empty.
572 const_iterator begin() const;
573
574 /// Return an iterator providing non-modifiable access to the past-the-end
575 /// position in the sequence of `VALUE` objects maintained by this
576 /// container.
577 ConstEndReturnType end() const;
578
579 /// Return the address of the non-modifiable first element in this
580 /// container.
581 const VALUE *data() const;
582
583 /// Return a reference providing non-modifiable access to the element at the specified `index`.
584 ///
585 /// \pre The behavior is undefined unless
586 /// `0 < size() && index < size()`.
587 const VALUE& operator[](size_t index) const;
588
589 /// Return number of elements in this container.
590 size_t size() const;
591};
592
593 // ======================================
594 // class TestValuesArray_DefaultConverter
595 // ======================================
596
597/// This `struct` provides a namespace for an utility function,
598/// `createInplace`, that creates an object of the (template parameter) type
599/// `VALUE` from a character identifier.
600template <class VALUE, class ALLOCATOR>
602{
603 // CLASS METHODS
604
605 /// Create an object of the (template parameter) type `VALUE` at the
606 /// specified `objPtr` address whose state is unique for the specified
607 /// `value`. Use the specified `allocator` to supply memory.
608 ///
609 /// \pre The behavior is undefined unless `0 <= value && value < 128` and `VALUE`
610 /// is contained in the macro
611 /// `BSLTF_TEMPLATETESTFACILITY_TEST_TYPES_ALL`.
612 static void createInplace(VALUE *objPtr, char value, ALLOCATOR allocator);
613};
614
615 // ======================================
616 // class TestValuesArray_PostIncrementPtr
617 // ======================================
618
619/// This class is a wrapper that encapsulates a reference, providing
620/// non-modifiable access to the element of `TestValuesArray` container.
621/// Object of this class is returned by post increment operator of
622/// TestValuesArray' container.
623template <class VALUE>
625{
626 private:
627 // DATA
628 const VALUE *d_data_p; // pointer to the value (not owned)
629
630 public:
631 // CREATORS
632
633 /// Create a `TestValuesArray_PostIncrementPtr` object having the value
634 /// of the specified `ptr`.
635 explicit TestValuesArray_PostIncrementPtr(const VALUE* ptr);
636
637 // ACCESSORS
638
639 /// Return a reference providing non-modifiable access to the object
640 /// referred to by this wrapper.
641 const VALUE& operator*() const;
642};
643
644// ============================================================================
645// INLINE DEFINITIONS
646// ============================================================================
647
648 // -----------------------------
649 // class TestValuesArrayIterator
650 // -----------------------------
651
652// CREATORS
653
654template <class VALUE>
655inline
657: d_data_p(0)
658, d_end_p(0)
659, d_dereferenceable_p(0)
660, d_isValid_p(0)
661{
662}
663
664template <class VALUE>
665inline
667 const VALUE *object,
668 const VALUE *end,
669 bool *dereferenceable,
670 bool *isValid)
671: d_data_p(object)
672, d_end_p(end)
673, d_dereferenceable_p(dereferenceable)
674, d_isValid_p(isValid)
675{
676 BSLS_ASSERT_SAFE(object);
677 BSLS_ASSERT_SAFE(end);
678 BSLS_ASSERT_SAFE(dereferenceable);
679 BSLS_ASSERT_SAFE(isValid);
680 BSLS_ASSERT_SAFE(*isValid);
681}
682
683template <class VALUE>
684inline
686 const TestValuesArrayIterator& original)
687: d_data_p(original.d_data_p)
688, d_end_p(original.d_end_p)
689, d_dereferenceable_p(original.d_dereferenceable_p)
690, d_isValid_p(original.d_isValid_p)
691{
692 BSLS_ASSERT_OPT(*original.d_isValid_p);
693}
694
695// MANIPULATORS
696template <class VALUE>
699{
700 BSLS_ASSERT_OPT(*other.d_isValid_p);
701
702 d_data_p = other.d_data_p;
703 d_end_p = other.d_end_p;
704 d_dereferenceable_p = other.d_dereferenceable_p;
705 d_isValid_p = other.d_isValid_p;
706
707 return *this;
708}
709
710template <class VALUE>
713{
714 BSLS_ASSERT_OPT(d_data_p != d_end_p);
715 BSLS_ASSERT_OPT(*d_isValid_p);
716
717 *d_dereferenceable_p = false;
718 *d_isValid_p = false;
719
720 ++d_data_p;
721 ++d_dereferenceable_p;
722 ++d_isValid_p;
723 return *this;
724}
725
726template <class VALUE>
729{
730 BSLS_ASSERT_OPT(*d_isValid_p);
731 BSLS_ASSERT_OPT(d_data_p != d_end_p);
732
734 this->operator++();
735 return result;
736}
737
738// ACCESSORS
739template <class VALUE>
740inline
742{
743 BSLS_ASSERT_OPT(*d_isValid_p);
744 BSLS_ASSERT_OPT(*d_dereferenceable_p);
745
746 *d_dereferenceable_p = false;
747 return *d_data_p;
748}
749
750template <class VALUE>
751inline
753{
754 BSLS_ASSERT_OPT(*d_isValid_p);
755 BSLS_ASSERT_OPT(*d_dereferenceable_p);
756
757 *d_dereferenceable_p = false;
758 return d_data_p;
759}
760
761template <class VALUE>
763{
764 return d_data_p;
765}
766
767 // -----------------------------
768 // class TestValuesArraySentinel
769 // -----------------------------
770
771// CREATORS
772template <class VALUE>
777
778template <class VALUE>
780: d_end_p(end)
781{
782}
783
784// ACCESSORS
785template <class VALUE>
787{
788 return d_end_p;
789}
790
791} // close package namespace
792
793// FREE OPERATORS
794template <class VALUE>
795inline
798{
799 BSLS_ASSERT_OPT(*lhs.d_isValid_p);
800 BSLS_ASSERT_OPT(*rhs.d_isValid_p);
801
802 return lhs.d_data_p == rhs.d_data_p;
803}
804
805template <class VALUE>
806inline
809{
810 BSLS_ASSERT_OPT(*lhs.d_isValid_p);
811 BSLS_ASSERT_OPT(*rhs.d_isValid_p);
812
813 return !(lhs == rhs);
814}
815
816template <class VALUE>
819{
820 return lhs.d_data_p == rhs.d_end_p;
821}
822
823template <class VALUE>
826{
827 return lhs.d_end_p == rhs.d_data_p;
828}
829
830template <class VALUE>
833{
834 return lhs.d_data_p != rhs.d_end_p;
835}
836
837template <class VALUE>
840{
841 return lhs.d_end_p != rhs.d_data_p;
842}
843
844namespace bsltf {
845 // ---------------------
846 // class TestValuesArray
847 // ---------------------
848
849// PRIVATE MANIPULATORS
850
851template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
852void TestValuesArray<VALUE, ALLOCATOR, CONVERTER, USE_SENTINEL>::initialize(
853 const char *spec)
854{
855 BSLS_ASSERT_SAFE(spec);
856
857 d_size = strlen(spec);
858
859 // Allocate all memory in one go.
860
861 size_type numBytes = static_cast<size_type>(
862 d_size * sizeof(VALUE) + 2 * (d_size + 1) * sizeof(bool));
863 size_type numMaxAlignedType =
866
867 AllocatorType alignAlloc(d_allocator);
868 d_data_p = reinterpret_cast<VALUE *>(AllocatorTraits::allocate(
869 alignAlloc, numMaxAlignedType));
870
871 d_dereferenceable_p = reinterpret_cast<bool *>(d_data_p + d_size);
872 d_validIterator_p = d_dereferenceable_p + d_size + 1;
873
874 for (int i = 0; '\0' != spec[i]; ++i) {
875 CONVERTER::createInplace(d_data_p + i, spec[i], d_allocator);
876 }
877
878 memset(d_dereferenceable_p, true, d_size * sizeof(bool));
879 d_dereferenceable_p[d_size] = false; // 'end' is never dereferenceable
880 memset(d_validIterator_p, true, (d_size + 1) * sizeof(bool));
881}
882
883template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
884inline
885typename
889{
890 return iterator(data() + d_size,
891 data() + d_size,
892 d_dereferenceable_p + d_size,
893 d_validIterator_p + d_size);
894}
895
896template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
897inline
898typename
905
906template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
907inline
908typename
912{
913 return const_iterator(data() + d_size,
914 data() + d_size,
915 d_dereferenceable_p + d_size,
916 d_validIterator_p + d_size);
917}
918
919template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
920inline
921typename
928
929// CREATORS
930template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
932: d_allocator(&bslma::MallocFreeAllocator::singleton())
933{
934 static const char DEFAULT_SPEC[] =
935 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
936
937 initialize(DEFAULT_SPEC);
938}
939
940template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
942 ALLOCATOR basicAllocator)
943: d_allocator(basicAllocator)
944{
945 static const char DEFAULT_SPEC[] =
946 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
947
948 initialize(DEFAULT_SPEC);
949}
950
951template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
952inline
954 const char *spec)
955: d_allocator(&bslma::MallocFreeAllocator::singleton())
956{
957 initialize(spec);
958}
959
960template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
961inline
963 const char *spec,
964 ALLOCATOR basicAllocator)
965: d_allocator(basicAllocator)
966{
967 initialize(spec);
968}
969
970template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
972{
973 for (size_t i = 0; i < d_size; ++i) {
974 bsl::allocator_traits<ALLOCATOR>::destroy(d_allocator, d_data_p + i);
975 }
976
977 size_type numBytes = static_cast<size_type>(
978 d_size * sizeof(VALUE) + 2 * (d_size + 1) * sizeof(bool));
979 size_type numMaxAlignedType =
982
983 AllocatorType alignAlloc(d_allocator);
984 AllocatorTraits::deallocate(
985 alignAlloc,
986 reinterpret_cast<bsls::AlignmentUtil::MaxAlignedType *>(
987 reinterpret_cast<void *>(d_data_p)),
988 numMaxAlignedType);
989 // The redundant cast to 'void *' persuades gcc/Solaris that there are
990 // no alignment issues to warn about.
991}
992
993// MANIPULATORS
994
995template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
996inline
997typename
1000{
1001 return iterator(data(),
1002 data() + d_size,
1003 d_dereferenceable_p,
1004 d_validIterator_p);
1005}
1006
1007template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1008inline
1009typename
1015
1016template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1017inline
1018typename
1021 size_t position)
1022{
1023 BSLS_ASSERT_SAFE(position <= size());
1024
1025 return iterator(data() + position,
1026 data() + d_size,
1027 d_dereferenceable_p + position,
1028 d_validIterator_p + position);
1029}
1030
1031template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1034{
1035 memset(d_dereferenceable_p, 1, d_size * sizeof(bool));
1036 d_dereferenceable_p[d_size] = false;
1037 memset(d_validIterator_p, 1, (d_size + 1) * sizeof(bool));
1038}
1039
1040// ACCESSORS
1041
1042template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1043inline
1044typename
1047{
1048 return const_iterator(data(),
1049 data() + d_size,
1050 d_dereferenceable_p,
1051 d_validIterator_p);
1052}
1053
1054template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1055inline
1056typename
1062
1063template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1064inline
1066 data() const
1067{
1068 return d_data_p;
1069}
1070
1071template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1072inline
1074operator[](size_t index) const
1075{
1076 BSLS_ASSERT_SAFE(0 < size() && index < size());
1077
1078 return data()[index];
1079}
1080
1081template <class VALUE, class ALLOCATOR, class CONVERTER, bool USE_SENTINEL>
1082inline
1084{
1085 return d_size;
1086}
1087
1088 // --------------------------------------
1089 // class TestValuesArray_DefaultConverter
1090 // --------------------------------------
1091
1092template <class VALUE, class ALLOCATOR>
1093inline
1095 VALUE *objPtr,
1096 char value,
1097 ALLOCATOR allocator)
1098{
1099 bsltf::TemplateTestFacility::emplace(objPtr, value, allocator);
1100}
1101
1102 // --------------------------------------
1103 // class TestValuesArray_PostIncrementPtr
1104 // --------------------------------------
1105
1106template <class VALUE>
1107inline
1109TestValuesArray_PostIncrementPtr(const VALUE* ptr)
1110: d_data_p(ptr)
1111{
1112 BSLS_ASSERT_SAFE(ptr);
1113}
1114
1115template <class VALUE>
1116inline
1118{
1119 return *d_data_p;
1120}
1121
1122} // close package namespace
1123
1124
1125#endif
1126
1127// ----------------------------------------------------------------------------
1128// Copyright 2013 Bloomberg Finance L.P.
1129//
1130// Licensed under the Apache License, Version 2.0 (the "License");
1131// you may not use this file except in compliance with the License.
1132// You may obtain a copy of the License at
1133//
1134// http://www.apache.org/licenses/LICENSE-2.0
1135//
1136// Unless required by applicable law or agreed to in writing, software
1137// distributed under the License is distributed on an "AS IS" BASIS,
1138// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1139// See the License for the specific language governing permissions and
1140// limitations under the License.
1141// ----------------------------- END-OF-FILE ----------------------------------
1142
1143/** @} */
1144/** @} */
1145/** @} */
Definition bslma_bslallocator.h:588
Definition bsltf_testvaluesarray.h:251
TestValuesArrayIterator()
Definition bsltf_testvaluesarray.h:656
TestValuesArrayIterator & operator=(const TestValuesArrayIterator &other)
Definition bsltf_testvaluesarray.h:698
friend bool operator!=(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArraySentinel< OTHER_VALUE > &)
TestValuesArrayIterator & operator++()
Definition bsltf_testvaluesarray.h:712
VALUE value_type
Definition bsltf_testvaluesarray.h:295
friend bool operator==(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArraySentinel< OTHER_VALUE > &)
const VALUE * pointer
Definition bsltf_testvaluesarray.h:297
friend bool operator!=(const TestValuesArraySentinel< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
friend bool operator==(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
ptrdiff_t difference_type
Definition bsltf_testvaluesarray.h:296
std::input_iterator_tag iterator_category
Definition bsltf_testvaluesarray.h:294
const VALUE * operator->() const
Definition bsltf_testvaluesarray.h:752
friend bool operator==(const TestValuesArraySentinel< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
const VALUE & operator*() const
Definition bsltf_testvaluesarray.h:741
const VALUE * address() const
Return the position (address) referenced by this iterator.
Definition bsltf_testvaluesarray.h:762
friend bool operator!=(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
const VALUE & reference
Standard iterator defined types [24.4.2].
Definition bsltf_testvaluesarray.h:300
Definition bsltf_testvaluesarray.h:389
friend bool operator!=(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArraySentinel< OTHER_VALUE > &)
const VALUE * address() const
Return the position (address) referenced by this sentinel.
Definition bsltf_testvaluesarray.h:786
friend bool operator==(const TestValuesArrayIterator< OTHER_VALUE > &, const TestValuesArraySentinel< OTHER_VALUE > &)
TestValuesArraySentinel()
Definition bsltf_testvaluesarray.h:773
friend bool operator!=(const TestValuesArraySentinel< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
friend bool operator==(const TestValuesArraySentinel< OTHER_VALUE > &, const TestValuesArrayIterator< OTHER_VALUE > &)
Definition bsltf_testvaluesarray.h:625
const VALUE & operator*() const
Definition bsltf_testvaluesarray.h:1117
TestValuesArray_PostIncrementPtr(const VALUE *ptr)
Definition bsltf_testvaluesarray.h:1109
Definition bsltf_testvaluesarray.h:467
TestValuesArrayIterator< VALUE > iterator
Iterator/Sentinel for this container.
Definition bsltf_testvaluesarray.h:507
TestValuesArraySentinel< const VALUE > const_sentinel
Definition bsltf_testvaluesarray.h:510
iterator index(size_t position)
Definition bsltf_testvaluesarray.h:1020
const VALUE & operator[](size_t index) const
Definition bsltf_testvaluesarray.h:1074
bsl::conditional< USE_SENTINEL, const_sentinel, const_iterator >::type ConstEndReturnType
Definition bsltf_testvaluesarray.h:516
TestValuesArraySentinel< VALUE > sentinel
Definition bsltf_testvaluesarray.h:508
void resetIterators()
Make all iterators dereferenceable and comparable again.
Definition bsltf_testvaluesarray.h:1033
TestValuesArrayIterator< const VALUE > const_iterator
Definition bsltf_testvaluesarray.h:509
bsl::conditional< USE_SENTINEL, sentinel, iterator >::type EndReturnType
Definition bsltf_testvaluesarray.h:513
sentinel privateEnd(BSLMF_TYPEIDENTITY_T(sentinel))
Definition bsltf_testvaluesarray.h:901
const VALUE * data() const
Definition bsltf_testvaluesarray.h:1066
~TestValuesArray()
Destroy this container and all contained elements.
Definition bsltf_testvaluesarray.h:971
EndReturnType end()
Definition bsltf_testvaluesarray.h:1011
iterator begin()
Definition bsltf_testvaluesarray.h:999
size_t size() const
Return number of elements in this container.
Definition bsltf_testvaluesarray.h:1083
TestValuesArray()
Definition bsltf_testvaluesarray.h:931
#define BSLMF_TYPEIDENTITY_T(...)
Definition bslmf_typeidentity.h:256
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
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
Definition bsltf_allocargumenttype.h:92
bool operator!=(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
bool operator==(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
Definition bslma_allocatortraits.h:1089
static void destroy(ALLOCATOR_TYPE &basicAllocator, ELEMENT_TYPE *elementAddr)
Definition bslma_allocatortraits.h:1549
Definition bslmf_conditional.h:123
Definition bslmf_integralconstant.h:261
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:307
@ BSLS_MAX_ALIGNMENT
Definition bsls_alignmentutil.h:300
static void emplace(TYPE *address, int identifier, ALLOCATOR allocator)
Definition bsltf_templatetestfacility.h:1223
Definition bsltf_testvaluesarray.h:602
static void createInplace(VALUE *objPtr, char value, ALLOCATOR allocator)
Definition bsltf_testvaluesarray.h:1094