BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlat_arrayfunctions.h
Go to the documentation of this file.
1/// @file bdlat_arrayfunctions.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_arrayfunctions.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_ARRAYFUNCTIONS
9#define INCLUDED_BDLAT_ARRAYFUNCTIONS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_arrayfunctions bdlat_arrayfunctions
15/// @brief Provide a namespace defining "array" functions.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_arrayfunctions
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_arrayfunctions-purpose"> Purpose</a>
25/// * <a href="#bdlat_arrayfunctions-classes"> Classes </a>
26/// * <a href="#bdlat_arrayfunctions-description"> Description </a>
27/// * <a href="#bdlat_arrayfunctions-usage"> Usage </a>
28/// * <a href="#bdlat_arrayfunctions-example-1-defining-an-array-type"> Example 1: Defining an "Array" Type </a>
29/// * <a href="#bdlat_arrayfunctions-example-2-using-the-infrastructure-via-general-methods"> Example 2: Using the Infrastructure Via General Methods </a>
30/// * <a href="#bdlat_arrayfunctions-example-3-defining-utility-functions"> Example 3: Defining Utility Functions </a>
31/// * <a href="#bdlat_arrayfunctions-example-4-achieving-type-independence"> Example 4: Achieving Type Independence </a>
32///
33/// # Purpose {#bdlat_arrayfunctions-purpose}
34/// Provide a namespace defining "array" functions.
35///
36/// # Classes {#bdlat_arrayfunctions-classes}
37///
38/// - bdlat_ArrayFunctions: namespace for calling "array" functions
39///
40/// # Description {#bdlat_arrayfunctions-description}
41/// The `bdlat_ArrayFunctions` `namespace` provided in this
42/// component defines parameterized functions that expose "array" behavior for
43/// "array" types. See the {`bdlat`} package-level documentation for a full
44/// description of "array" types.
45///
46/// The functions in this namespace allow users to:
47/// * obtain the number of elements in an array (`size`).
48/// * set the number of elements in an array (`resize`).
49/// * manipulate an element in an array using a parameterized manipulator
50/// (`manipulateElement`). and
51/// * access an element in an array using a parameterized accessor
52/// (`accessElement`).
53///
54/// A type becomes part of the `bdlat` "array" framework by creating, in the
55/// namespace where the type is defined, overloads of the following two (free)
56/// functions and two (free) function templates. Note that the placeholder
57/// `YOUR_TYPE` is not a template argument and should be replaced with the name
58/// of the type being plugged into the framework.
59/// @code
60/// // MANIPULATORS
61/// template <class MANIPULATOR>
62/// int bdlat_arrayManipulateElement(YOUR_TYPE *array,
63/// MANIPULATOR& manipulator,
64/// int index);
65/// // Invoke the specified 'manipulator' on the address of the element at
66/// // the specified 'index' of the specified 'array'. Return the value
67/// // from the invocation of 'manipulator'. The behavior is undefined
68/// // unless '0 <= index' and 'index < bdlat_arraySize(*array)'.
69///
70/// void resize(YOUR_TYPE *array, int newSize);
71/// // Set the size of the specified modifiable 'array' to the specified
72/// // 'newSize'. If 'newSize > bdlat_arraySize(*array)', then
73/// // 'newSize - bdlat_arraySize(*array)' elements with default values
74/// // (i.e., 'ElementType()') are appended to 'array'. If
75/// // 'newSize < bdlat_arraySize(*array)', then the
76/// // 'bdlat_arraySize(*array) - newSize' elements at the end of 'array'
77/// // are destroyed. The behavior is undefined unless '0 <= newSize'.
78///
79/// // ACCESSORS
80/// template <class ACCESSOR>
81/// int bdlat_arrayAccessElement(const YOUR_TYPE& array,
82/// ACCESSOR& accessor,
83/// int index);
84/// // Invoke the specified 'accessor' on a 'const'-reference to the
85/// // element at the specified 'index' of the specified 'array'. Return
86/// // the value from the invocation of 'accessor'. The behavior is
87/// // undefined unless '0 <= index' and 'index < bdlat_arraySize(array)'.
88///
89/// bsl::size_t bdlat_arraySize(const YOUR_TYPE& array);
90/// // Return the number of elements in the specified 'array'.
91/// @endcode
92/// The "array" type must also define two meta-functions in the
93/// `bdlat_ArrayFunctions` namespace:
94///
95/// * the meta-function `IsArray` contains a compile-time constant `value` that
96/// is non-zero if the parameterized `TYPE` exposes "array" behavior, and
97/// * the `ElementType` meta-function contains a `typedef` `Type` that
98/// specifies the type of the element stored in the parameterized "array"
99/// type.
100///
101/// Note that `bsl::vector<TYPE>` is already part of the `bdlat`
102/// infrastructure for "array" types because this component also provides
103/// overloads of the required functions and meta-function specializations.
104///
105/// ## Usage {#bdlat_arrayfunctions-usage}
106///
107///
108/// This section illustrates intended use of this component.
109///
110/// ### Example 1: Defining an "Array" Type {#bdlat_arrayfunctions-example-1-defining-an-array-type}
111///
112///
113/// Suppose you had a type, `mine::MyIntArray`, that provides the essential
114/// features of an "array" type.
115/// @code
116/// namespace BloombergLP {
117/// namespace mine {
118///
119/// class MyIntArray {
120///
121/// int *d_data_p;
122/// bsl::size_t d_size;
123///
124/// public:
125/// // CREATORS
126/// MyIntArray()
127/// : d_data_p(0)
128/// , d_size(0)
129/// {
130/// }
131///
132/// ~MyIntArray()
133/// {
134/// bsl::free(d_data_p);
135/// }
136///
137/// // MANIPULATORS
138/// void resize(bsl::size_t newSize);
139///
140/// int& value(bsl::size_t index)
141/// {
142/// assert(index < d_size);
143///
144/// return d_data_p[index];
145/// }
146///
147/// // ACCESSORS
148/// const int& value(bsl::size_t index) const
149/// {
150/// assert(index < d_size);
151///
152/// return d_data_p[index];
153/// }
154///
155/// bsl::size_t size() const
156/// {
157/// return d_size;
158/// }
159/// };
160///
161/// void MyIntArray::resize(bsl::size_t newSize)
162/// {
163/// // Always match buffer to size exactly.
164///
165/// if (d_size == newSize) {
166/// return; // RETURN
167/// }
168///
169/// int *newData = static_cast<int *>(bsl::malloc(sizeof(int)
170/// * newSize));
171/// if (d_size < newSize) {
172/// bsl::memcpy(newData, d_data_p, d_size * sizeof(int));
173/// std::memset(newData + d_size,
174/// 0,
175/// (newSize - d_size) * sizeof(int));
176///
177/// } else {
178/// bsl::memcpy(newData, d_data_p, newSize);
179/// }
180///
181/// bsl::free(d_data_p);
182/// d_data_p = newData;
183/// d_size = newSize;
184/// }
185///
186/// } // close namespace mine
187/// } // close enterprise namespace
188/// @endcode
189/// We can now make `mine::MyIntArray` expose "array" behavior by implementing
190/// the necessary `bdlat_ArrayFunctions` for `MyIntArray` inside the `mine`
191/// namespace and defining the required meta-functions withing the
192/// `bdlat_ArrayFunctions` namespace.
193///
194/// First, we should forward declare all the functions that we will implement
195/// inside the `mine` namespace:
196/// @code
197/// namespace BloombergLP {
198/// namespace mine {
199///
200/// // MANIPULATORS
201/// template <class MANIPULATOR>
202/// int bdlat_arrayManipulateElement(MyIntArray *array,
203/// MANIPULATOR& manipulator,
204/// int index);
205/// // Invoke the specified 'manipulator' on the address of the element at
206/// // the specified 'index' of the specified 'array'. Return the value
207/// // from the invocation of 'manipulator'. The behavior is undefined
208/// // unless '0 <= index' and 'index < bdlat_arraySize(*array)'.
209///
210/// void bdlat_arrayResize(MyIntArray *array, int newSize);
211/// // Set the size of the specified modifiable 'array' to the specified
212/// // 'newSize'. If 'newSize > bdlat_arraySize(*array)', then
213/// // 'newSize - bdlat_arraySize(*array)' elements with default values
214/// // (i.e., 'ElementType()') are appended to 'array'. If
215/// // 'newSize < bdlat_arraySize(*array)', then the
216/// // 'bdlat_arraySize(*array) - newSize' elements at the end of 'array'
217/// // are destroyed. The behavior is undefined unless '0 <= newSize'.
218///
219/// // ACCESSORS
220/// template <class ACCESSOR>
221/// int bdlat_arrayAccessElement(const MyIntArray& array,
222/// ACCESSOR& accessor,
223/// int index);
224/// // Invoke the specified 'accessor' on a 'const'-reference to the
225/// // element at the specified 'index' of the specified 'array'. Return
226/// // the value from the invocation of 'accessor'. The behavior is
227/// // undefined unless '0 <= index' and 'index < bdlat_arraySize(array)'.
228///
229/// bsl::size_t bdlat_arraySize(const MyIntArray& array);
230/// // Return the number of elements in the specified 'array'.
231///
232/// } // close namespace mine
233/// } // close enterprise namespace
234/// @endcode
235/// Then, we will implement these functions. Recall that the two (non-template)
236/// functions should be defined in some `.cpp` file, unless you choose to make
237/// them `inline` functions.
238/// @code
239/// namespace BloombergLP {
240/// namespace mine {
241///
242/// // MANIPULATORS
243/// template <class MANIPULATOR>
244/// int bdlat_arrayManipulateElement(MyIntArray *array,
245/// MANIPULATOR& manipulator,
246/// int index)
247/// {
248/// assert(array);
249/// assert(0 <= index);
250/// assert(static_cast<bsl::size_t>(index) < array->size());
251///
252/// return manipulator(&array->value(index));
253/// }
254///
255/// void bdlat_arrayResize(MyIntArray *array, int newSize)
256/// {
257/// assert(array);
258/// assert(0 <= newSize);
259///
260/// array->resize(newSize);
261/// }
262///
263/// // ACCESSORS
264/// template <class ACCESSOR>
265/// int bdlat_arrayAccessElement(const MyIntArray& array,
266/// ACCESSOR& accessor,
267/// int index)
268/// {
269/// assert(0 <= index);
270/// assert(static_cast<bsl::size_t>(index) < array.size());
271///
272/// return accessor(array.value(index));
273/// }
274///
275/// bsl::size_t bdlat_arraySize(const MyIntArray& array)
276/// {
277/// return array.size();
278/// }
279///
280/// } // close namespace mine
281/// } // close enterprise namespace
282/// @endcode
283/// Finally, we specialize the `IsArray` and `ElementType` meta-functions
284/// in the `bdlat_ArrayFunctions` namespace for the
285/// `mine::MyIntArray` type:
286/// @code
287/// namespace BloombergLP {
288/// namespace bdlat_ArrayFunctions {
289///
290/// // TRAITS
291/// template <>
292/// struct IsArray<mine::MyIntArray> : bsl::true_type {
293/// };
294///
295/// template <>
296/// struct ElementType<mine::MyIntArray> {
297/// typedef int Type;
298/// };
299///
300/// } // close namespace bdlat_ArrayFunctions
301/// } // close enterprise namespace
302/// @endcode
303/// This completes the `bdlat` infrastructure for `mine::MyIntArray` and
304/// allows the generic software to recognize the type as an array abstraction.
305///
306/// ### Example 2: Using the Infrastructure Via General Methods {#bdlat_arrayfunctions-example-2-using-the-infrastructure-via-general-methods}
307///
308///
309/// The `bdlat` "array" framework provides a set of fundamental operations
310/// common to any "array" type. We can build upon these operations to make our
311/// own utilities, or use them on our own types that are plugged into the
312/// framework, like `mine::MyIntArray`, which we created in {Example 1}. For
313/// example, we can use the (fundamental) operations in the
314/// `bdlat_ArrayFunctions` namespace to operate on `mine::MyIntArray`, even
315/// though they have no knowledge of that type in particular:
316/// @code
317/// void usageMakeArray()
318/// {
319/// BSLMF_ASSERT(bdlat_ArrayFunctions::IsArray<mine::MyIntArray>::value);
320///
321/// mine::MyIntArray array;
322/// assert(0 == bdlat_ArrayFunctions::size(array));
323///
324/// bdlat_ArrayFunctions::resize(&array, 8);
325/// assert(8 == bdlat_ArrayFunctions::size(array));
326///
327/// bdlat_ArrayFunctions::resize(&array, 4);
328/// assert(4 == bdlat_ArrayFunctions::size(array));
329/// }
330/// @endcode
331/// To perform operations on the elements of an array requires use of the
332/// functions that employ accessor and manipulator functors. For example:
333/// @code
334/// template <class ELEMENT_TYPE>
335/// class GetElementAccessor {
336///
337/// // DATA
338/// ELEMENT_TYPE *d_element_p;
339///
340/// public:
341/// // CREATORS
342/// explicit GetElementAccessor(ELEMENT_TYPE *value)
343/// : d_element_p(value)
344/// {
345/// }
346///
347/// // MANIPULATORS
348/// int operator()(const ELEMENT_TYPE& elementValue)
349/// {
350/// *d_element_p = elementValue;
351/// return 0;
352/// }
353/// };
354///
355/// template<class ELEMENT_TYPE>
356/// class SetElementManipulator {
357///
358/// // DATA
359/// ELEMENT_TYPE d_value;
360///
361/// public:
362/// // CREATORS
363/// SetElementManipulator(const ELEMENT_TYPE& value)
364/// : d_value(value)
365/// {
366/// }
367///
368/// // ACCESSOR
369/// int operator()(ELEMENT_TYPE *element) const
370/// {
371/// *element = d_value;
372/// return 0;
373/// }
374/// };
375/// @endcode
376/// Notice that these functors make few assumptions of `ELEMENT_TYPE`, merely
377/// that it is copy constructable and copy assignable.
378///
379/// With these definitions we can now use the generic functions to set and
380/// get values from an `mine::MyIntArray` object:
381/// @code
382/// void usageArrayElements()
383/// {
384/// mine::MyIntArray array;
385/// bdlat_ArrayFunctions::resize(&array, 4);
386///
387/// // Confirm initial array elements from resize.
388///
389/// int value;
390/// GetElementAccessor<int> accessor(&value);
391///
392/// for (int index = 0; index < 4; ++index) {
393/// int rc = bdlat_ArrayFunctions::accessElement(array,
394/// accessor,
395/// index);
396/// assert(0 == rc);
397/// assert(0 == value)
398/// }
399///
400/// // Set element 'index * 10' as its value;
401///
402/// for (int index = 0; index < 4; ++index) {
403/// SetElementManipulator<int> manipulator(index * 10);
404///
405/// int rc = bdlat_ArrayFunctions::manipulateElement(&array,
406/// manipulator,
407/// index);
408/// assert(0 == rc);
409/// }
410///
411/// // Confirm new value of each element.
412///
413/// for (int index = 0; index < 4; ++index) {
414/// int rc = bdlat_ArrayFunctions::accessElement(array,
415/// accessor,
416/// index);
417/// assert(0 == rc);
418/// assert(index * 10 == value);
419/// }
420/// }
421/// @endcode
422///
423/// ### Example 3: Defining Utility Functions {#bdlat_arrayfunctions-example-3-defining-utility-functions}
424///
425///
426/// Creating functor objects for each operation can be tedious and error prone;
427/// consequently, those types are often executed via utility functions.
428///
429/// Suppose we want to create utilities for getting and setting the elements of
430/// an arbitrary "array" type. We might define a utility `struct`, `ArrayUtil`,
431/// a namespace for those functions:
432/// @code
433/// struct ArrayUtil {
434///
435/// // CLASS METHODS
436/// template <class ARRAY_TYPE>
437/// static int getElement(typename bdlat_ArrayFunctions
438/// ::ElementType<ARRAY_TYPE>::Type *value,
439/// const ARRAY_TYPE& object,
440/// int index)
441/// // Load to the specified 'value' the element at the specified
442/// // 'index' of the specified 'object' array. Return 0 if the
443/// // element is successfully loaded to 'value', and a non-zero value
444/// // otherwise. This function template requires that the specified
445/// // 'ARRAY_TYPE' is a 'bdlat' "array" type. The behavior is
446/// // undefined unless '0 <= index' and
447/// // 'index < bdlat_ArrayFunctions::size(object)'.
448/// {
449/// BSLMF_ASSERT(bdlat_ArrayFunctions::IsArray<ARRAY_TYPE>::value);
450///
451/// typedef typename bdlat_ArrayFunctions
452/// ::ElementType<ARRAY_TYPE>::Type ElementType;
453///
454/// GetElementAccessor<ElementType> elementAccessor(value);
455///
456/// return bdlat_ArrayFunctions::accessElement(object,
457/// elementAccessor,
458/// index);
459/// }
460///
461/// template <class ARRAY_TYPE>
462/// static int setElement(
463/// ARRAY_TYPE *object,
464/// int index,
465/// const typename bdlat_ArrayFunctions::ElementType<ARRAY_TYPE>
466/// ::Type& value)
467/// // Assign the specified 'value' to the element of the specified
468/// // 'object' array at the specified 'index'. Return 0 if the
469/// // element is successfully assigned to 'value', and a non-zero
470/// // value otherwise. This function template requires that the
471/// // specified 'ARRAY_TYPE' is a 'bdlat' "array" type. The behavior
472/// // is undefined unless '0 <= index' and
473/// // 'index < bdlat_ArrayFunctions::size(*object)'.
474/// {
475/// BSLMF_ASSERT(bdlat_ArrayFunctions::IsArray<ARRAY_TYPE>::value);
476///
477/// typedef typename bdlat_ArrayFunctions::ElementType<ARRAY_TYPE>
478/// ::Type ElementType;
479///
480/// SetElementManipulator<ElementType> manipulator(value);
481///
482/// return bdlat_ArrayFunctions::manipulateElement(object,
483/// manipulator,
484/// index);
485/// }
486/// };
487/// @endcode
488/// Now, we can use these functors to write generic utility functions for
489/// getting and setting the value types of arbitrary "array" classes.
490/// @code
491/// void myUsageScenario()
492/// {
493/// mine::MyIntArray array;
494/// bdlat_ArrayFunctions::resize(&array, 4);
495///
496/// // Confirm initial values.
497///
498/// for (int index = 0; index < 4; ++index) {
499/// int value;
500/// int rc = ArrayUtil::getElement(&value, array, index);
501/// assert(0 == rc);
502/// assert(0 == value);
503/// }
504///
505/// // Set element 'index * 10' as its value;
506///
507/// for (int index = 0; index < 4; ++index) {
508/// int value = index * 10;
509/// int rc = ArrayUtil::setElement(&array, index, value);
510/// assert(0 == rc);
511/// }
512///
513/// // Confirm value of each element.
514///
515/// for (int index = 0; index < 4; ++index) {
516/// int value;
517/// int rc = ArrayUtil::getElement(&value, array, index);
518/// assert(0 == rc);
519/// assert(index * 10 == value);
520/// }
521/// }
522/// @endcode
523///
524/// ### Example 4: Achieving Type Independence {#bdlat_arrayfunctions-example-4-achieving-type-independence}
525///
526///
527/// Suppose we have another type such as `your::YourFloatArray`, shown below:
528/// @code
529/// namespace BloombergLP {
530/// namespace your {
531///
532/// class MyFloatArray {
533///
534/// float *d_data_p;
535/// bsl::size_t d_size;
536/// bsl::size_t d_capacity;
537///
538/// public:
539/// // CREATORS
540/// MyFloatArray()
541/// : d_data_p(0)
542/// , d_size(0)
543/// {
544/// }
545///
546/// ~MyFloatArray()
547/// {
548/// delete[] d_data_p;
549/// }
550///
551/// // MANIPULATORS
552/// void setSize(bsl::size_t newSize); // Too large for inline.
553///
554/// float& element(bsl::size_t index)
555/// {
556/// assert(index < d_size);
557///
558/// return d_data_p[index];
559/// }
560///
561/// // ACCESSORS
562/// const float& element(bsl::size_t index) const
563/// {
564/// assert(index < d_size);
565///
566/// return d_data_p[index];
567/// }
568///
569/// bsl::size_t numElements() const
570/// {
571/// return d_size;
572/// }
573///
574/// bsl::size_t capacity() const
575/// {
576/// return d_capacity;
577/// }
578/// };
579/// @endcode
580/// Notice that while there are many similarities to `mine::MyIntArray`, there
581/// are also significant differences:
582/// * The element type is `float`, not `int`.
583/// * Many of the accessors are named differently (e.g., `numElements` instead
584/// of `size`, `setSize` instead of `resize`).
585/// * There is an additional attribute, `capacity`, because this class has a
586/// `setSize` method (not shown) that reduces calls to the heap by over
587/// allocating when the size is increased beyond the current capacity.
588///
589/// Nevertheless, since `your::YourFloatArray` also provides the functions
590/// and types expected by the `bdlat` infrastructure (not shown) we can
591/// successfully use `your::FloatArray` value instead of `mine::MyIntArray`
592/// in the previous usage scenario, with no other changes:
593/// @code
594/// void yourUsageScenario()
595/// {
596/// your::YourFloatArray array;
597/// bdlat_ArrayFunctions::resize(&array, 4);
598///
599/// // Confirm initial values.
600///
601/// for (int index = 0; index < 4; ++index) {
602/// float value;
603/// int rc = ArrayUtil::getElement(&value, array, index);
604/// assert(0 == rc);
605/// assert(0.0 == value);
606/// }
607///
608/// // Set element 'index * 10' as its value;
609///
610/// for (int index = 0; index < 4; ++index) {
611/// float value = static_cast<float>(index * 10);
612/// int rc = ArrayUtil::setElement(&array, index, value);
613/// assert(0 == rc);
614/// }
615///
616/// // Confirm value of each element.
617///
618/// for (int index = 0; index < 4; ++index) {
619/// float value;
620/// int rc = ArrayUtil::getElement(&value, array, index);
621/// assert(0 == rc);
622/// assert(static_cast<float>(index * 10) == value);
623/// }
624/// }
625/// @endcode
626/// Notice that syntax and order of `bdlat_ArrayFunctions` function
627/// calls have not been changed. The only difference is that the element
628/// type has changed from `int` to `float`.
629///
630/// Finally, instead of defining a new "array" type, we could substitute the
631/// existing type template `bsl::vector`. Note that this component
632/// provides specializations of the `bdlat_ArrayFunctions` for that
633/// type. Since the accessor and manipulator functions we created earlier are
634/// type neutral, we can simply drop `bsl::vector<bsl::string>` into our
635/// familiar scenario:
636/// @code
637/// void anotherUsageScenario()
638/// {
639/// bsl::vector<bsl::string> array; // STANDARD ARRAY TYPE
640/// bdlat_ArrayFunctions::resize(&array, 4);
641///
642/// // Confirm initial values.
643///
644/// for (int index = 0; index < 4; ++index) {
645/// bsl::string value;
646/// int rc = ArrayUtil::getElement(&value, array, index);
647/// assert(0 == rc);
648/// assert("" == value);
649/// }
650///
651/// // Set element 'index * 10' as its value;
652///
653/// for (int index = 0; index < 4; ++index) {
654/// bsl::ostringstream oss; oss << (index * 10);
655/// int rc = ArrayUtil::setElement(&array, index, oss.str());
656/// assert(0 == rc);
657/// }
658///
659/// // Confirm value of each element.
660///
661/// for (int index = 0; index < 4; ++index) {
662/// bsl::string value;
663/// int rc = ArrayUtil::getElement(&value, array, index);
664///
665/// bsl::ostringstream oss; oss << (index * 10);
666///
667/// assert(0 == rc);
668/// assert(oss.str() == value);
669/// }
670/// }
671/// @endcode
672/// @}
673/** @} */
674/** @} */
675
676/** @addtogroup bdl
677 * @{
678 */
679/** @addtogroup bdlat
680 * @{
681 */
682/** @addtogroup bdlat_arrayfunctions
683 * @{
684 */
685
686#include <bdlscm_version.h>
687
688#include <bdlat_bdeatoverrides.h>
689
691
692#include <bsl_cstddef.h>
693#include <bsl_cstdlib.h>
694#include <bsl_vector.h>
695
696
697
698 // ==============================
699 // namespace bdlat_ArrayFunctions
700 // ==============================
701
703 // This 'namespace' provides functions that expose "array" behavior for
704 // "array" types. Specializations are provided for 'bsl::vector<TYPE>'.
705 // See the component-level documentation for more information.
706
707 // META-FUNCTIONS
708
709 /// This meta-function should contain a typedef `Type` that specifies
710 /// the type of element stored in an array of the parameterized `TYPE`.
711 template <class TYPE>
713
714 /// This `struct` should be specialized for third-party types that are
715 /// need to expose "array" behavior. See the component-level
716 /// documentation for further information.
717 template <class TYPE>
719 };
720
721 // MANIPULATORS
722
723 /// Invoke the specified `manipulator` on the address of the element at
724 /// the specified `index` of the specified `array`. Return the value
725 /// from the invocation of `manipulator`. The behavior is undefined
726 /// unless `0 <= index` and `index < size(*array)`.
727 template <class TYPE, class MANIPULATOR>
728 int manipulateElement(TYPE *array,
729 MANIPULATOR& manipulator,
730 int index);
731
732 /// Set the size of the specified modifiable `array` to the specified
733 /// `newSize`. If `newSize > size(array)`, then `newSize - size(array)`
734 /// elements with default values are appended to `array`. If
735 /// `newSize < size(array)`, then the `size(array) - newSize` elements
736 /// at the end of `array` are destroyed. The behavior is undefined
737 /// unless `0 <= newSize`.
738 template <class TYPE>
739 void resize(TYPE *array, int newSize);
740
741 // ACCESSORS
742
743 /// Invoke the specified `accessor` on the non-modifiable element at the
744 /// specified `index` of the specified `array`. Return the value from
745 /// the invocation of `accessor`. The behavior is undefined unless
746 /// `0 <= index` and `index < size(array)`.
747 template <class TYPE, class ACCESSOR>
748 int accessElement(const TYPE& array,
749 ACCESSOR& accessor,
750 int index);
751
752 /// Return the number of elements in the specified `array`.
753 template <class TYPE>
754 bsl::size_t size(const TYPE& array);
755
756} // close namespace bdlat_ArrayFunctions
757
758 // ========================
759 // bsl::vector declarations
760 // ========================
761
762namespace bdlat_ArrayFunctions {
763 // This namespace declaration adds the implementation of the "array" traits
764 // for 'bsl::vector' to 'bdlat_ArrayFunctions'. Note that 'bsl::vector' is
765 // the canonical "array" type.
766
767 // META-FUNCTIONS
768 template <class TYPE, class ALLOC>
769 struct IsArray<bsl::vector<TYPE, ALLOC> > : bsl::true_type {
770 };
771
772 template <class TYPE, class ALLOC>
773 struct ElementType<bsl::vector<TYPE, ALLOC> > {
774 typedef TYPE Type;
775 };
776
777 // MANIPULATORS
778 template <class TYPE, class ALLOC, class MANIPULATOR>
780 MANIPULATOR& manipulator,
781 int index);
782
783 template <class TYPE, class ALLOC>
785
786 // ACCESSORS
787 template <class TYPE, class ALLOC, class ACCESSOR>
789 ACCESSOR& accessor,
790 int index);
791
792 template <class TYPE, class ALLOC>
793 bsl::size_t bdlat_arraySize(const bsl::vector<TYPE, ALLOC>& array);
794
795} // close namespace bdlat_ArrayFunctions
796
797// ============================================================================
798// INLINE DEFINITIONS
799// ============================================================================
800
801 // -------------------------
802 // namespace-level functions
803 // -------------------------
804
805// MANIPULATORS
806template <class TYPE, class MANIPULATOR>
807inline
809 MANIPULATOR& manipulator,
810 int index)
811{
812 return bdlat_arrayManipulateElement(array, manipulator, index);
813}
814
815template <class TYPE>
816inline
817void bdlat_ArrayFunctions::resize(TYPE *array, int newSize)
818{
819 bdlat_arrayResize(array, newSize);
820}
821
822// ACCESSORS
823template <class TYPE, class ACCESSOR>
824inline
825int bdlat_ArrayFunctions::accessElement(const TYPE& array,
826 ACCESSOR& accessor,
827 int index)
828{
829 return bdlat_arrayAccessElement(array, accessor, index);
830}
831
832template <class TYPE>
833inline
834bsl::size_t bdlat_ArrayFunctions::size(const TYPE& array)
835{
836 return bdlat_arraySize(array);
837}
838
839 // -----------------------
840 // bsl::vector definitions
841 // -----------------------
842
843// MANIPULATORS
844template <class TYPE, class ALLOC, class MANIPULATOR>
845inline
848 MANIPULATOR& manipulator,
849 int index)
850{
851 TYPE& element = (*array)[index];
852 return manipulator(&element);
853}
854
855template <class TYPE, class ALLOC>
856inline
858 int newSize)
859{
860 array->resize(newSize);
861}
862
863// ACCESSORS
864template <class TYPE, class ALLOC, class ACCESSOR>
865inline
867 const bsl::vector<TYPE, ALLOC>& array,
868 ACCESSOR& accessor,
869 int index)
870{
871 return accessor(array[index]);
872}
873
874template <class TYPE, class ALLOC>
875inline
877 const bsl::vector<TYPE, ALLOC>& array)
878{
879 return array.size();
880}
881
882
883
884#endif
885
886// ----------------------------------------------------------------------------
887// Copyright 2015 Bloomberg Finance L.P.
888//
889// Licensed under the Apache License, Version 2.0 (the "License");
890// you may not use this file except in compliance with the License.
891// You may obtain a copy of the License at
892//
893// http://www.apache.org/licenses/LICENSE-2.0
894//
895// Unless required by applicable law or agreed to in writing, software
896// distributed under the License is distributed on an "AS IS" BASIS,
897// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
898// See the License for the specific language governing permissions and
899// limitations under the License.
900// ----------------------------- END-OF-FILE ----------------------------------
901
902/** @} */
903/** @} */
904/** @} */
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
Definition bslstl_vector.h:1025
void resize(size_type newSize)
Definition bslstl_vector.h:3616
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlat_arrayfunctions.h:702
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *array, int newSize)
void bdlat_arrayResize(bsl::vector< TYPE, ALLOC > *array, int newSize)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
int accessElement(const TYPE &array, ACCESSOR &accessor, int index)
int bdlat_arrayAccessElement(const bsl::vector< TYPE, ALLOC > &array, ACCESSOR &accessor, int index)
bsl::size_t bdlat_arraySize(const bsl::vector< TYPE, ALLOC > &array)
int bdlat_arrayManipulateElement(bsl::vector< TYPE, ALLOC > *array, MANIPULATOR &manipulator, int index)
Definition bdlb_printmethods.h:283
TYPE Type
Definition bdlat_arrayfunctions.h:774
Definition bdlat_arrayfunctions.h:712
Definition bdlat_arrayfunctions.h:718
Definition bslmf_integralconstant.h:244