BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlat_symbolicconverter.h
Go to the documentation of this file.
1/// @file bdlat_symbolicconverter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_symbolicconverter.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_SYMBOLICCONVERTER
9#define INCLUDED_BDLAT_SYMBOLICCONVERTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_symbolicconverter bdlat_symbolicconverter
15/// @brief Provide a utility for convert types with matching member symbols.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_symbolicconverter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_symbolicconverter-purpose"> Purpose</a>
25/// * <a href="#bdlat_symbolicconverter-classes"> Classes </a>
26/// * <a href="#bdlat_symbolicconverter-description"> Description </a>
27/// * <a href="#bdlat_symbolicconverter-usage"> Usage </a>
28/// * <a href="#bdlat_symbolicconverter-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bdlat_symbolicconverter-purpose}
31/// Provide a utility for convert types with matching member symbols.
32///
33/// # Classes {#bdlat_symbolicconverter-classes}
34///
35/// - bdlat_SymbolicConverter: symbolic converter utility
36///
37/// @see
38///
39/// # Description {#bdlat_symbolicconverter-description}
40/// The `bdlat_SymbolicConverter` utility provided by this
41/// component defines a single parameterized function `convert`. The `convert`
42/// function takes two arguments: a destination and a source object. The
43/// destination and source objects may be of different types.
44///
45/// Each type can fall into one of the following categories:
46/// @code
47/// Category Reference
48/// -------- ---------
49/// Sequence bdlat_sequencefunctions
50/// Choice bdlat_choicefunctions
51/// Array bdlat_arrayfunctions
52/// Enumeration bdlat_enumfunctions
53/// NullableValue bdlat_nullablevaluefunctions
54/// CustomizedType bdlat_customizedtypefunctions
55/// Simple basic C++ fundamental types & other value-semantic types
56/// @endcode
57/// The `bdlat_SymbolicConverter` utility converts from one type to another
58/// using the following criteria:
59/// @code
60/// Destination Category Source Category Comments
61/// -------------------- --------------- --------
62/// Sequence Sequence The conversion will fail if each
63/// attribute in the set of attributes
64/// from the source does not have a
65/// corresponding attribute (with the
66/// same name) in the destination. The
67/// conversion will also fail if any
68/// attributes from the source fail to
69/// convert to the corresponding
70/// attribute in the destination. Any
71/// attribute in the destination that
72/// does not have a corresponding
73/// attribute in the source will be set
74/// to its default value.
75///
76/// Choice Choice The conversion will fail if the
77/// destination does not have a
78/// selection with the same name as the
79/// current selection in the source.
80/// The conversion will also fail if
81/// the selection from the source fails
82/// to convert to the corresponding
83/// selection in the destination. If
84/// nothing is selected in the source,
85/// then the destination will be reset.
86///
87/// Array Array The conversion will fail if the
88/// elements in the source fail to
89/// convert to the elements in the
90/// destination. Upon completion, the
91/// destination array will contain the
92/// same number of elements as the
93/// source array.
94///
95/// Enumeration Enumeration The conversion will fail if the
96/// destination does not have a string
97/// value that is identical to the
98/// string value of the source.
99///
100/// Enumeration char/short/int The conversion will fail if the
101/// destination does not have an
102/// enumerator with the numeric value
103/// of the source.
104///
105/// char/short/int Enumeration The conversion will fail if the
106/// numeric value of the enumeration is
107/// outside the bounds of the
108/// destination type.
109///
110/// Enumeration bsl::string The conversion will fail if the
111/// destination does not have an
112/// enumerator with the symbolic string
113/// name of the source.
114///
115/// bsl::string Enumeration This conversion always succeeds.
116///
117/// NullableValue NullableValue The conversion will fail if the
118/// source has a value that fails to
119/// convert to the destination value.
120/// If the source is null, then the
121/// destination is nulled.
122///
123/// NullableValue AnyType The conversion will fail if the
124/// source fails to convert to the
125/// destination value.
126///
127/// AnyType NullableValue The conversion will fail if the
128/// source is not null and the value in
129/// the source fails to convert to the
130/// destination. If the source is
131/// null, then the destination will
132/// be set to its default value.
133///
134/// CustomizedType CustomizedType The conversion will fail if the
135/// base value in the source fails to
136/// convert to the base value in the
137/// destination and the base value is
138/// able to convert to the customized
139/// value.
140///
141/// CustomizedType AnyType The conversion will fail if the
142/// source fails to convert to the base
143/// value in the destination and the
144/// base value is able to convert to
145/// the customized value.
146///
147/// AnyType CustomizedType The conversion will fail if the
148/// base value in the source fails to
149/// convert to the destination.
150///
151/// SimpleType SimpleType The conversion will fail if there
152/// is no accessible compile-time
153/// assignment operator from the
154/// destination to the source. This is
155/// determined using
156/// 'bslmf_isconvertible'.
157/// @endcode
158/// Any other combination of destination and source categories will fail to
159/// convert.
160///
161/// ## Usage {#bdlat_symbolicconverter-usage}
162///
163///
164/// This section illustrates intended use of this component.
165///
166/// ### Example 1: Basic Usage {#bdlat_symbolicconverter-example-1-basic-usage}
167///
168///
169/// This component can be used with types supported by the `bdlat` framework.
170/// In particular, types generated by the `bas_codegen.pl` tool can be used.
171/// For example, suppose we have the following XML schema inside a file called
172/// `xsdfile.xsd`:
173/// @code
174/// <?xml version='1.0' encoding='UTF-8'?>
175/// <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
176/// xmlns:bdem='http://bloomberg.com/schemas/bdem'
177/// elementFormDefault='unqualified'>
178///
179/// <xs:complexType name='Employee'>
180/// <xs:sequence>
181/// <xs:element name='Name' type='string'/>
182/// <xs:element name='Dept' type='string'/>
183/// <xs:element name='Age' type='int'/>
184/// <xs:element name='Salary' type='float'/>
185/// </xs:sequence>
186/// </xs:complexType>
187///
188/// <xs:complexType name='Trainee'>
189/// <xs:sequence>
190/// <xs:element name='Name' type='string'/>
191/// <xs:element name='Dept' type='string'/>
192/// <xs:element name='Age' type='int'/>
193/// </xs:sequence>
194/// </xs:complexType>
195///
196/// </xs:schema>
197/// @endcode
198/// Using the `bas_codegen.pl` tool, we can generate C++ classes for this
199/// schema:
200/// @code
201/// $ bas_codegen.pl -g h -g cpp -p test xsdfile.xsd
202/// @endcode
203/// This tool will generate the header and implementation files for the
204/// @ref test_employee and @ref test_trainee components in the current directory.
205///
206/// Now suppose we want to create a `hireTrainee` function, that converts a
207/// trainee to an employee. Such a function could be written as follows:
208/// @code
209/// #include <test_employee.h>
210/// #include <test_trainee.h>
211///
212/// #include <bdlat_symbolicconverter.h>
213///
214/// using namespace BloombergLP;
215///
216/// int hireTrainee(test::Employee *result,
217/// const test::Trainee& trainee,
218/// float salary)
219/// {
220/// int retCode = bdlat_SymbolicConverter::convert(result, trainee);
221///
222/// result->salary() = salary;
223///
224/// return retCode;
225/// }
226/// @endcode
227/// The `hireTrainee` function can be used as follows:
228/// @code
229/// void usageExample()
230/// {
231/// test::Trainee trainee;
232///
233/// trainee.name() = "Bob";
234/// trainee.dept() = "RnD";
235/// trainee.age() = 24;
236///
237/// test::Employee employee;
238///
239/// int result = hireTrainee(&employee, trainee, 20000.00f);
240///
241/// assert(0 == result);
242/// assert("Bob" == employee.name());
243/// assert("RnD" == employee.dept());
244/// assert(24 == employee.age());
245/// assert(20000.00f == employee.salary());
246/// }
247/// @endcode
248/// @}
249/** @} */
250/** @} */
251
252/** @addtogroup bdl
253 * @{
254 */
255/** @addtogroup bdlat
256 * @{
257 */
258/** @addtogroup bdlat_symbolicconverter
259 * @{
260 */
261
262#include <bdlscm_version.h>
263
264#include <bdlat_arrayfunctions.h>
265#include <bdlat_bdeatoverrides.h>
268#include <bdlat_enumfunctions.h>
271#include <bdlat_typecategory.h>
273
274#include <bdlb_printmethods.h>
275
276#include <bslmf_switch.h>
277
278#include <bsls_assert.h>
279#include <bsls_review.h>
280
281#include <bsl_ostream.h>
282#include <bsl_string.h>
283
284
285
286 // ==============================
287 // struct bdlat_SymbolicConverter
288 // ==============================
289
290/// This utility contains a single `convert` function that converts a value
291/// from one type to another compatible type.
293
294 /// Convert the value of the specified `rhs` object to the specified
295 /// (modifiable) `lhs` object. Optionally specify an `errorStream` to
296 /// print error messages. Return 0 on success and a non-zero value
297 /// otherwise. The supported conversions are described in the
298 /// @ref bdlat_symbolicconverter component-level documentation.
299 template <class LHS_TYPE, class RHS_TYPE>
300 static
301 int convert(LHS_TYPE *lhs, const RHS_TYPE &rhs);
302 template <class LHS_TYPE, class RHS_TYPE>
303 static
304 int convert(LHS_TYPE *lhs, const RHS_TYPE &rhs, bsl::ostream &errorStream);
305};
306
307// --- Anything below this line is implementation specific. Do not use. ----
308
309 // =================================
310 // class bdlat_SymbolicConverter_Imp
311 // =================================
312
313/// This class contains implementation functions for this component.
314///
315/// See @ref bdlat_symbolicconverter
317
318 // PRIVATE DATA MEMBERS
319 bsl::ostream *d_errorStream_p; // held, not owned
320
321 public:
322 // IMPLEMENTATION MANIPULATORS
323
324 /// Convert to sequence from sequence.
325 template <class LHS_TYPE, class RHS_TYPE>
326 int convert(LHS_TYPE *lhs,
328 const RHS_TYPE& rhs,
329 bdlat_TypeCategory::Sequence rhsCategory);
330
331 /// Convert to choice from choice.
332 template <class LHS_TYPE, class RHS_TYPE>
333 int convert(LHS_TYPE *lhs,
334 bdlat_TypeCategory::Choice lhsCategory,
335 const RHS_TYPE& rhs,
336 bdlat_TypeCategory::Choice rhsCategory);
337
338 /// Convert to array from array.
339 template <class LHS_TYPE, class RHS_TYPE>
340 int convert(LHS_TYPE *lhs,
341 bdlat_TypeCategory::Array lhsCategory,
342 const RHS_TYPE& rhs,
343 bdlat_TypeCategory::Array rhsCategory);
344
345 /// Convert to enum from enum.
346 template <class LHS_TYPE, class RHS_TYPE>
347 int convert(LHS_TYPE *lhs,
349 const RHS_TYPE& rhs,
351
352 /// Convert to enum from simple type.
353 template <class LHS_TYPE, class RHS_TYPE>
354 int convert(LHS_TYPE *lhs,
356 const RHS_TYPE& rhs,
357 bdlat_TypeCategory::Simple rhsCategory);
358
359 /// Convert to simple type from enum.
360 template <class LHS_TYPE, class RHS_TYPE>
361 int convert(LHS_TYPE *lhs,
362 bdlat_TypeCategory::Simple lhsCategory,
363 const RHS_TYPE& rhs,
365
366 /// Convert to nullable from nullable.
367 template <class LHS_TYPE, class RHS_TYPE>
368 int convert(LHS_TYPE *lhs,
370 const RHS_TYPE& rhs,
372
373 /// Convert to nullable from non-nullable.
374 template <class LHS_TYPE, class RHS_TYPE, class RHS_CATEGORY>
375 int convert(LHS_TYPE *lhs,
377 const RHS_TYPE& rhs,
378 RHS_CATEGORY rhsCategory);
379
380 /// Convert to non-nullable from nullable.
381 template <class LHS_TYPE, class LHS_CATEGORY, class RHS_TYPE>
382 int convert(LHS_TYPE *lhs,
383 LHS_CATEGORY lhsCategory,
384 const RHS_TYPE& rhs,
386
387 /// Convert to customized type from nullable. Note that this overload
388 /// is required to resolve ambiguities when there are nullable and
389 /// customized types in the same sequence.
390 template <class LHS_TYPE, class RHS_TYPE>
391 int convert(LHS_TYPE *lhs,
393 const RHS_TYPE& rhs,
395
396 /// Convert to customized from customized.
397 template <class LHS_TYPE, class RHS_TYPE>
398 int convert(LHS_TYPE *lhs,
400 const RHS_TYPE& rhs,
402
403 /// Convert to customized from non-customized.
404 template <class LHS_TYPE, class RHS_TYPE, class RHS_CATEGORY>
405 int convert(LHS_TYPE *lhs,
407 const RHS_TYPE& rhs,
408 RHS_CATEGORY rhsCategory);
409
410 /// Convert to non-customized from customized.
411 template <class LHS_TYPE, class LHS_CATEGORY, class RHS_TYPE>
412 int convert(LHS_TYPE *lhs,
413 LHS_CATEGORY lhsCategory,
414 const RHS_TYPE& rhs,
416
417 /// Convert to nullable from customized. Note that this overload is
418 /// required to resolve ambiguities when there are nullable and
419 /// customized types in the same sequence.
420 template <class LHS_TYPE, class RHS_TYPE>
421 int convert(LHS_TYPE *lhs,
423 const RHS_TYPE& rhs,
425
426 /// Convert to simple from simple of the same type. Note that this just
427 /// evaluates to an assignment using the assignment operator.
428 template <class LHS_TYPE, class RHS_TYPE>
429 int convert(LHS_TYPE *lhs,
430 bdlat_TypeCategory::Simple lhsCategory,
431 const RHS_TYPE& rhs,
432 bdlat_TypeCategory::Simple rhsCategory);
433
434 /// No match found. This function does nothing, it just returns a
435 /// FAILURE code (to be used to detect type-mismatch at runtime).
436 template <class LHS_TYPE,
437 class LHS_CATEGORY,
438 class RHS_TYPE,
439 class RHS_CATEGORY>
440 int convert(LHS_TYPE *lhs,
441 LHS_CATEGORY lhsCategory,
442 const RHS_TYPE& rhs,
443 RHS_CATEGORY rhsCategory);
444
445 /// Resolve dynamic types.
446 template <class LHS_TYPE, class RHS_TYPE>
447 int resolveDynamicTypes(LHS_TYPE *lhs,
449 const RHS_TYPE& rhs,
451 template <class LHS_TYPE,
452 class RHS_TYPE,
453 class RHS_CATEGORY>
454 int resolveDynamicTypes(LHS_TYPE *lhs,
456 const RHS_TYPE& rhs,
457 RHS_CATEGORY rhsCategory);
458 template <class LHS_TYPE,
459 class LHS_CATEGORY,
460 class RHS_TYPE>
461 int resolveDynamicTypes(LHS_TYPE *lhs,
462 LHS_CATEGORY lhsCategory,
463 const RHS_TYPE& rhs,
465 template <class LHS_TYPE,
466 class LHS_CATEGORY,
467 class RHS_TYPE,
468 class RHS_CATEGORY>
469 int resolveDynamicTypes(LHS_TYPE *lhs,
470 LHS_CATEGORY lhsCategory,
471 const RHS_TYPE& rhs,
472 RHS_CATEGORY rhsCategory);
473
474 private:
475 // NOT IMPLEMENTED
478
479 public:
480 // CREATORS
481
482 /// Create the imp object.
484
485 /// Destroy this object.
487
488 // MANIPULATORS
489
490 /// Implementation for convert function.
491 template <class LHS_TYPE, class RHS_TYPE>
492 int convert(LHS_TYPE *lhs,
493 const RHS_TYPE& rhs);
494
495 /// Return a reference to the error stream.
496 bsl::ostream& errorStream();
497};
498
499 // =====================================================
500 // class bdlat_SymbolicConverter_StoreValue<LVALUE_TYPE>
501 // =====================================================
502
503/// This visitor assigns the value of the visited member to
504/// `d_destination_p`.
505///
506/// See @ref bdlat_symbolicconverter
507template <class LVALUE_TYPE>
509
510 // PRIVATE DATA MEMBERS
511 LVALUE_TYPE *d_destination_p; // held, not owned
512 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
513
514 public:
515 // CREATORS
517 LVALUE_TYPE *destination,
519
520 // ACCESSORS
521
522 /// Assign the specified `object` to `*d_lValue_p`.
523 template <class RVALUE_TYPE, class INFO_TYPE>
524 int operator()(const RVALUE_TYPE& object,
525 const INFO_TYPE&) const;
526
527 /// Assign the specified `object` to `*d_lValue_p`.
528 template <class RVALUE_TYPE>
529 int operator()(const RVALUE_TYPE& object) const;
530};
531
532 // ====================================================
533 // class bdlat_SymbolicConverter_LoadValue<RVALUE_TYPE>
534 // ====================================================
535
536/// This visitor assigns `d_value` to the visited member.
537///
538/// See @ref bdlat_symbolicconverter
539template <class RVALUE_TYPE>
541
542 // PRIVATE DATA MEMBERS
543 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
544 const RVALUE_TYPE& d_value; // held, not owned
545
546 public:
547 // CREATORS
549 const RVALUE_TYPE& value,
551
552 // ACCESSORS
553
554 /// Assign `d_value` to the specified `*object`.
555 template <class LVALUE_TYPE, class INFO_TYPE>
556 int operator()(LVALUE_TYPE *object,
557 const INFO_TYPE&) const;
558
559 /// Assign `d_value` to the specified `*object`.
560 template <class LVALUE_TYPE>
561 int operator()(LVALUE_TYPE *object) const;
562};
563
564 // ============================================================
565 // class bdlat_SymbolicConverter_StoreInSequence<SEQUENCE_TYPE>
566 // ============================================================
567
568/// This visitor is used when assigning to a sequence. It will visit each
569/// member from the source object. Each time a member is visited, it will
570/// use the `LoadValue` visitor template to visit the member with the same
571/// name in the destination sequence. This will cause the value of the
572/// member in the source object to be assigned to the member (with the same
573/// name) of the destination sequence object.
574///
575/// See @ref bdlat_symbolicconverter
576template <class SEQUENCE_TYPE>
578
579 // PRIVATE DATA MEMBERS
580 SEQUENCE_TYPE *d_destination_p; // held, not owned
581 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
582
583 public:
584 // CREATORS
586 SEQUENCE_TYPE *destination,
588
589 // ACCESSORS
590 template <class SOURCE_MEMBER_TYPE, class INFO_TYPE>
591 int operator()(const SOURCE_MEMBER_TYPE& sourceMember,
592 const INFO_TYPE& info) const;
593};
594
595 // ========================================================
596 // class bdlat_SymbolicConverter_StoreInChoice<CHOICE_TYPE>
597 // ========================================================
598
599/// Similar to `StoreInSequence` but this is for choice.
600///
601/// See @ref bdlat_symbolicconverter
602template <class CHOICE_TYPE>
604
605 // PRIVATE DATA MEMBERS
606 CHOICE_TYPE *d_destination_p; // held, not owned
607 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
608
609 public:
610 // CREATORS
612 CHOICE_TYPE *destination,
614
615 // ACCESSORS
616 template <class SOURCE_MEMBER_TYPE, class INFO_TYPE>
617 int operator()(const SOURCE_MEMBER_TYPE& sourceMember,
618 const INFO_TYPE& info) const;
619};
620
621 // =============================================================
622 // class bdlat_SymbolicConverter_StoreInArrayElement<ARRAY_TYPE>
623 // =============================================================
624
625/// Assign the value of the visited object to the `d_index`th element inside
626/// `d_array_p`.
627///
628/// See @ref bdlat_symbolicconverter
629template <class ARRAY_TYPE>
631
632 // PRIVATE DATA MEMBERS
633 ARRAY_TYPE *d_array_p; // held, not owned
634 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
635 int d_index; // element index to assign to
636
637 public:
638 // CREATORS
640 ARRAY_TYPE *array,
641 int index,
643
644 // ACCESSORS
645 template <class SOURCE_ELEMENT_TYPE>
646 int operator()(const SOURCE_ELEMENT_TYPE& sourceElement) const;
647};
648
649 // ============================================================
650 // class bdlat_SymbolicConverter_StoreInNullable<NULLABLE_TYPE>
651 // ============================================================
652
653/// Similar to `StoreInSequence` but this is for nullable.
654///
655/// See @ref bdlat_symbolicconverter
656template <class NULLABLE_TYPE>
658
659 // PRIVATE DATA MEMBERS
660 NULLABLE_TYPE *d_destination_p; // held, not owned
661 bdlat_SymbolicConverter_Imp *d_imp_p; // held, not owned
662
663 public:
664 // CREATORS
666 NULLABLE_TYPE *destination,
668
669 // ACCESSORS
670 template <class VALUE_TYPE>
671 int operator()(const VALUE_TYPE& value) const;
672};
673
674// ============================================================================
675// PROXY CLASSES
676// ============================================================================
677
678 // =========================================================
679 // struct bdlat_SymbolicConverter_Imp_resolveDynamicRhsProxy
680 // =========================================================
681
682/// Component-private struct. Do not use.
683template <class LHS_TYPE, class LHS_CATEGORY>
685
686 // DATA MEMBERS
688 LHS_TYPE *d_lhs_p;
689
690 // CREATORS
691
692 // Creators have been omitted to allow simple static initialization of this
693 // struct.
694
695 // FUNCTIONS
696 template <class TYPE>
697 inline
698 int operator()(const TYPE&, bslmf::Nil)
699 {
701 return -2;
702 }
703
704 template <class TYPE, class ANY_CATEGORY>
705 inline
706 int operator()(const TYPE& object, ANY_CATEGORY category)
707 {
709 LHS_CATEGORY(),
710 object,
711 category);
712 }
713};
714
715 // =========================================================
716 // struct bdlat_SymbolicConverter_Imp_resolveDynamicLhsProxy
717 // =========================================================
718
719/// Component-private struct. Do not use.
720template <class RHS_TYPE, class RHS_CATEGORY>
722
723 // DATA MEMBERS
725 const RHS_TYPE *d_rhs_p;
726
727 // CREATORS
728
729 // Creators have been omitted to allow simple static initialization of this
730 // struct.
731
732 // FUNCTIONS
733 template <class TYPE>
734 inline
736 {
738 return -3;
739 }
740
741 template <class TYPE, class ANY_CATEGORY>
742 inline
743 int operator()(TYPE *object, ANY_CATEGORY category)
744 {
745 return d_instance_p->resolveDynamicTypes(object,
746 category,
747 *d_rhs_p,
748 RHS_CATEGORY());
749 }
750};
751
752// ============================================================================
753// INLINE DEFINITIONS
754// ============================================================================
755
756 // ---------------------------------
757 // class bdlat_SymbolicConverter_Imp
758 // ---------------------------------
759
760// PRIVATE MANIPULATORS
761
762template <class LHS_TYPE, class RHS_TYPE>
763inline
766 const RHS_TYPE& rhs,
768{
770
771 return bdlat_SequenceFunctions::accessAttributes(rhs, storeInLhs);
772}
773
774template <class LHS_TYPE, class RHS_TYPE>
777 const RHS_TYPE& rhs,
779{
780 enum { k_SUCCESS = 0 };
781
783
787
788 return k_SUCCESS; // RETURN
789 }
790
791 return bdlat_ChoiceFunctions::accessSelection(rhs, storeInLhs);
792}
793
794template <class LHS_TYPE, class RHS_TYPE>
797 const RHS_TYPE& rhs,
799{
800 enum { k_SUCCESS = 0, k_FAILURE = -4 };
801
802 const int size = static_cast<int>(bdlat_ArrayFunctions::size(rhs));
803
805
806 for (int i = 0; i < size; ++i) {
808 storeInLhs(lhs, i, this);
809
810 if (0 != bdlat_ArrayFunctions::accessElement(rhs, storeInLhs, i)) {
811 return k_FAILURE; // RETURN
812 }
813 }
814
815 return k_SUCCESS;
816}
817
818template <class LHS_TYPE, class RHS_TYPE>
819inline
822 const RHS_TYPE& rhs,
824{
825 bsl::string str;
826
828
830 str.data(),
831 static_cast<int>(str.length()));
832}
833
834template <class LHS_TYPE, class RHS_TYPE>
835inline
838 const RHS_TYPE& rhs,
840{
841 return bdlat_ValueTypeFunctions::assign(lhs, rhs);
842}
843
844template <class LHS_TYPE, class RHS_TYPE>
845inline
848 const RHS_TYPE& rhs,
850{
851 return bdlat_ValueTypeFunctions::assign(lhs, rhs);
852}
853
854template <class LHS_TYPE, class RHS_TYPE>
856 LHS_TYPE *lhs,
858 const RHS_TYPE& rhs,
860{
861 enum { k_SUCCESS = 0 };
862
865
866 return k_SUCCESS; // RETURN
867 }
868
870
871 return bdlat_NullableValueFunctions::accessValue(rhs, storeInLhs);
872}
873
874template <class LHS_TYPE, class RHS_TYPE, class RHS_CATEGORY>
875inline
877 LHS_TYPE *lhs,
879 const RHS_TYPE& rhs,
880 RHS_CATEGORY)
881{
883
884 return storeInLhs(rhs);
885}
886
887template <class LHS_TYPE, class LHS_CATEGORY, class RHS_TYPE>
889 LHS_TYPE *lhs,
890 LHS_CATEGORY,
891 const RHS_TYPE& rhs,
893{
894 enum { k_SUCCESS = 0 };
895
897 // ignore the value and let '*lhs' contain its *default* value
898 return k_SUCCESS; // RETURN
899 }
900
901 bdlat_SymbolicConverter_StoreValue<LHS_TYPE> storeIntoLhs(lhs, this);
902
903 return bdlat_NullableValueFunctions::accessValue(rhs, storeIntoLhs);
904}
905
906template <class LHS_TYPE, class RHS_TYPE>
908 LHS_TYPE *lhs,
910 const RHS_TYPE& rhs,
912{
913 enum { k_SUCCESS = 0 };
914
916 // ignore the value and let '*lhs' contain its *default* value
917 return k_SUCCESS; // RETURN
918 }
919
920 bdlat_SymbolicConverter_StoreValue<LHS_TYPE> storeIntoLhs(lhs, this);
921
922 return bdlat_NullableValueFunctions::accessValue(rhs, storeIntoLhs);
923}
924
925template <class LHS_TYPE, class RHS_TYPE>
926inline
936
937template <class LHS_TYPE, class RHS_TYPE, class RHS_CATEGORY>
939 LHS_TYPE *lhs,
941 const RHS_TYPE& rhs,
942 RHS_CATEGORY)
943{
944 enum { k_FAILURE = -5 };
945
946 typedef typename
948
949 LhsBaseType lhsBaseValue;
950
951 if (0 != convert(&lhsBaseValue, rhs)) {
952 return k_FAILURE; // RETURN
953 }
954
956 lhsBaseValue);
957}
958
959template <class LHS_TYPE, class LHS_CATEGORY, class RHS_TYPE>
960inline
962 LHS_TYPE *lhs,
963 LHS_CATEGORY,
964 const RHS_TYPE& rhs,
966{
967 return convert(lhs,
969}
970
971template <class LHS_TYPE, class RHS_TYPE>
972inline
982
983template <class LHS_TYPE, class RHS_TYPE>
984inline
987 const RHS_TYPE& rhs,
989{
990 return bdlat_ValueTypeFunctions::assign(lhs, rhs);
991}
992
993template <class LHS_TYPE,
994 class LHS_CATEGORY,
995 class RHS_TYPE,
996 class RHS_CATEGORY>
997inline
999 LHS_CATEGORY,
1000 const RHS_TYPE&,
1001 RHS_CATEGORY)
1002{
1003 enum { k_FAILURE = -6 };
1004
1005 return k_FAILURE;
1006}
1007
1008template <class LHS_TYPE, class RHS_TYPE>
1009inline
1011 LHS_TYPE *lhs,
1013 const RHS_TYPE& rhs,
1015{
1017 LHS_TYPE,
1018 bdlat_TypeCategory::DynamicType> proxy = { this, lhs };
1019
1021}
1022
1023template <class LHS_TYPE, class RHS_TYPE, class RHS_CATEGORY>
1024inline
1026 LHS_TYPE *lhs,
1028 const RHS_TYPE& rhs,
1029 RHS_CATEGORY)
1030{
1032 RHS_TYPE,
1033 RHS_CATEGORY> proxy = { this, &rhs };
1034
1036}
1037
1038template <class LHS_TYPE, class LHS_CATEGORY, class RHS_TYPE>
1039inline
1041 LHS_TYPE *lhs,
1042 LHS_CATEGORY,
1043 const RHS_TYPE& rhs,
1045{
1047 LHS_TYPE,
1048 LHS_CATEGORY> proxy = { this, lhs };
1049
1051}
1052
1053template <class LHS_TYPE,
1054 class LHS_CATEGORY,
1055 class RHS_TYPE,
1056 class RHS_CATEGORY>
1057inline
1059 LHS_TYPE *lhs,
1060 LHS_CATEGORY lhsCategory,
1061 const RHS_TYPE& rhs,
1062 RHS_CATEGORY rhsCategory)
1063{
1064 return convert(lhs, lhsCategory, rhs, rhsCategory);
1065}
1066
1067// CREATORS
1068
1069inline
1070bdlat_SymbolicConverter_Imp::bdlat_SymbolicConverter_Imp(
1071 bsl::ostream *errorStream)
1072: d_errorStream_p(errorStream)
1073{
1074 BSLS_ASSERT(d_errorStream_p);
1075}
1076
1077// MANIPULATORS
1078
1079template <class LHS_TYPE, class RHS_TYPE>
1080inline
1082 const RHS_TYPE& rhs)
1083{
1084 typedef typename bdlat_TypeCategory::Select<LHS_TYPE>::Type LhsCategory;
1085 typedef typename bdlat_TypeCategory::Select<RHS_TYPE>::Type RhsCategory;
1086
1087 return resolveDynamicTypes(lhs, LhsCategory(), rhs, RhsCategory());
1088}
1089
1090inline
1092{
1093 return *d_errorStream_p;
1094}
1095
1096 // -----------------------------------------------------
1097 // class bdlat_SymbolicConverter_StoreValue<LVALUE_TYPE>
1098 // -----------------------------------------------------
1099
1100// CREATORS
1101
1102template <class LVALUE_TYPE>
1103inline
1105bdlat_SymbolicConverter_StoreValue(LVALUE_TYPE *destination,
1107: d_destination_p(destination)
1108, d_imp_p(imp)
1109{
1110}
1111
1112// ACCESSORS
1113
1114template <class LVALUE_TYPE>
1115template <class RVALUE_TYPE, class INFO_TYPE>
1116inline
1118 const RVALUE_TYPE& object,
1119 const INFO_TYPE&) const
1120{
1121 return d_imp_p->convert(d_destination_p, object);
1122}
1123
1124template <class LVALUE_TYPE>
1125template <class RVALUE_TYPE>
1126inline
1128 const RVALUE_TYPE& object) const
1129{
1130 return d_imp_p->convert(d_destination_p, object);
1131}
1132
1133 // ----------------------------------------------------
1134 // class bdlat_SymbolicConverter_LoadValue<RVALUE_TYPE>
1135 // ----------------------------------------------------
1136
1137// CREATORS
1138
1139template <class RVALUE_TYPE>
1140inline
1143 const RVALUE_TYPE& value,
1145: d_imp_p(imp)
1146, d_value(value)
1147{
1148}
1149
1150// ACCESSORS
1151
1152template <class RVALUE_TYPE>
1153template <class LVALUE_TYPE, class INFO_TYPE>
1154inline
1156 LVALUE_TYPE *object,
1157 const INFO_TYPE&) const
1158{
1159 return d_imp_p->convert(object, d_value);
1160}
1161
1162template <class RVALUE_TYPE>
1163template <class LVALUE_TYPE>
1164inline
1166 LVALUE_TYPE *object) const
1167{
1168 return d_imp_p->convert(object, d_value);
1169}
1170
1171 // ------------------------------------------------------------
1172 // class bdlat_SymbolicConverter_StoreInSequence<SEQUENCE_TYPE>
1173 // ------------------------------------------------------------
1174
1175// CREATORS
1176
1177template <class SEQUENCE_TYPE>
1178inline
1181 SEQUENCE_TYPE *destination,
1183: d_destination_p(destination)
1184, d_imp_p(imp)
1185{
1186}
1187
1188// ACCESSORS
1189
1190template <class SEQUENCE_TYPE>
1191template <class SOURCE_MEMBER_TYPE, class INFO_TYPE>
1192inline
1194 const SOURCE_MEMBER_TYPE& sourceMember,
1195 const INFO_TYPE& info) const
1196{
1197 enum { k_SUCCESS = 0, k_FAILURE = -7 };
1198
1200 sourceMember,
1201 d_imp_p);
1202
1203 if (0 != bdlat_SequenceFunctions::manipulateAttribute(d_destination_p,
1204 loadSourceValue,
1205 info.name(),
1206 info.nameLength())) {
1207 d_imp_p->errorStream()
1208 << "Failed to convert attribute '"
1209 << bslstl::StringRef(info.name(), info.nameLength()) << "'\n";
1210
1211 return k_FAILURE; // RETURN
1212 }
1213
1214 return k_SUCCESS;
1215}
1216
1217 // --------------------------------------------------------
1218 // class bdlat_SymbolicConverter_StoreInChoice<CHOICE_TYPE>
1219 // --------------------------------------------------------
1220
1221// CREATORS
1222
1223template <class CHOICE_TYPE>
1224inline
1226bdlat_SymbolicConverter_StoreInChoice(CHOICE_TYPE *destination,
1228: d_destination_p(destination)
1229, d_imp_p(imp)
1230{
1231}
1232
1233// ACCESSORS
1234
1235template <class CHOICE_TYPE>
1236template <class SOURCE_MEMBER_TYPE, class INFO_TYPE>
1238 const SOURCE_MEMBER_TYPE& sourceMember,
1239 const INFO_TYPE& info) const
1240{
1241 enum { k_SUCCESS = 0, k_FAILURE = -8 };
1242
1243 // Make the selection.
1244
1245 if (0 != bdlat_ChoiceFunctions::makeSelection(d_destination_p,
1246 info.name(),
1247 info.nameLength())) {
1248 d_imp_p->errorStream()
1249 << "Failed to make selection '"
1250 << bslstl::StringRef(info.name(), info.nameLength()) << "'\n";
1251
1252 return k_FAILURE; // RETURN
1253 }
1254
1255 // Assign the value.
1256
1258 sourceMember,
1259 d_imp_p);
1260
1261 if (0 != bdlat_ChoiceFunctions::manipulateSelection(d_destination_p,
1262 loadSourceValue)) {
1263 d_imp_p->errorStream()
1264 << "Failed to convert selection '"
1265 << bslstl::StringRef(info.name(), info.nameLength()) << "'\n";
1266
1267 return k_FAILURE; // RETURN
1268 }
1269
1270 return k_SUCCESS;
1271}
1272
1273 // -------------------------------------------------------------
1274 // class bdlat_SymbolicConverter_StoreInArrayElement<ARRAY_TYPE>
1275 // -------------------------------------------------------------
1276
1277// CREATORS
1278
1279template <class ARRAY_TYPE>
1280inline
1283 int index,
1285: d_array_p(array)
1286, d_imp_p(imp)
1287, d_index(index)
1288{
1289}
1290
1291// ACCESSORS
1292
1293template <class ARRAY_TYPE>
1294template <class SOURCE_ELEMENT_TYPE>
1295inline
1297 const SOURCE_ELEMENT_TYPE& sourceElement) const
1298{
1300 sourceElement,
1301 d_imp_p);
1302
1304 loadSourceValue,
1305 d_index);
1306}
1307
1308 // ------------------------------------------------------------
1309 // class bdlat_SymbolicConverter_StoreInNullable<NULLABLE_TYPE>
1310 // ------------------------------------------------------------
1311
1312// CREATORS
1313
1314template <class NULLABLE_TYPE>
1315inline
1318 NULLABLE_TYPE *destination,
1320: d_destination_p(destination)
1321, d_imp_p(imp)
1322{
1323}
1324
1325// ACCESSORS
1326
1327template <class NULLABLE_TYPE>
1328template <class VALUE_TYPE>
1329inline
1331 const VALUE_TYPE& value) const
1332{
1334
1335 // Assign the value.
1336
1338 d_imp_p);
1339
1340 return bdlat_NullableValueFunctions::manipulateValue(d_destination_p,
1341 loadSourceValue);
1342}
1343
1344 // ------------------------------
1345 // struct bdlat_SymbolicConverter
1346 // ------------------------------
1347
1348template <class LHS_TYPE, class RHS_TYPE>
1349inline
1351 const RHS_TYPE& rhs)
1352{
1353 bsl::ostream nullStream(0);
1354 return bdlat_SymbolicConverter::convert(lhs, rhs, nullStream);
1355}
1356
1357template <class LHS_TYPE, class RHS_TYPE>
1358inline
1360 const RHS_TYPE& rhs,
1361 bsl::ostream& errorStream)
1362{
1364
1365 bdlat_SymbolicConverter_Imp imp(&errorStream);
1366
1367 return imp.convert(lhs, rhs);
1368}
1369
1370
1371
1372#endif
1373
1374// ----------------------------------------------------------------------------
1375// Copyright 2015 Bloomberg Finance L.P.
1376//
1377// Licensed under the Apache License, Version 2.0 (the "License");
1378// you may not use this file except in compliance with the License.
1379// You may obtain a copy of the License at
1380//
1381// http://www.apache.org/licenses/LICENSE-2.0
1382//
1383// Unless required by applicable law or agreed to in writing, software
1384// distributed under the License is distributed on an "AS IS" BASIS,
1385// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386// See the License for the specific language governing permissions and
1387// limitations under the License.
1388// ----------------------------- END-OF-FILE ----------------------------------
1389
1390/** @} */
1391/** @} */
1392/** @} */
Definition bdlat_symbolicconverter.h:316
~bdlat_SymbolicConverter_Imp()=default
Destroy this object.
Definition bdlat_symbolicconverter.h:540
Definition bdlat_symbolicconverter.h:630
Definition bdlat_symbolicconverter.h:603
Definition bdlat_symbolicconverter.h:657
Definition bdlat_symbolicconverter.h:577
Definition bdlat_symbolicconverter.h:508
Definition bslstl_string.h:1281
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6601
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6477
bdlat_SymbolicConverter_LoadValue(const RVALUE_TYPE &value, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1142
int operator()(const SOURCE_MEMBER_TYPE &sourceMember, const INFO_TYPE &info) const
Definition bdlat_symbolicconverter.h:1237
bsl::ostream & errorStream()
Return a reference to the error stream.
Definition bdlat_symbolicconverter.h:1091
bdlat_SymbolicConverter_StoreInSequence(SEQUENCE_TYPE *destination, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1180
bdlat_SymbolicConverter_StoreInArrayElement(ARRAY_TYPE *array, int index, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1282
int operator()(const SOURCE_ELEMENT_TYPE &sourceElement) const
Definition bdlat_symbolicconverter.h:1296
bdlat_SymbolicConverter_StoreValue(LVALUE_TYPE *destination, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1105
bdlat_SymbolicConverter_StoreInNullable(NULLABLE_TYPE *destination, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1317
int operator()(const VALUE_TYPE &value) const
Definition bdlat_symbolicconverter.h:1330
int operator()(const SOURCE_MEMBER_TYPE &sourceMember, const INFO_TYPE &info) const
Definition bdlat_symbolicconverter.h:1193
bdlat_SymbolicConverter_StoreInChoice(CHOICE_TYPE *destination, bdlat_SymbolicConverter_Imp *imp)
Definition bdlat_symbolicconverter.h:1226
int operator()(LVALUE_TYPE *object, const INFO_TYPE &) const
Assign d_value to the specified *object.
Definition bdlat_symbolicconverter.h:1155
int operator()(const RVALUE_TYPE &object, const INFO_TYPE &) const
Assign the specified object to *d_lValue_p.
Definition bdlat_symbolicconverter.h:1117
int convert(LHS_TYPE *lhs, bdlat_TypeCategory::Sequence lhsCategory, const RHS_TYPE &rhs, bdlat_TypeCategory::Sequence rhsCategory)
Convert to sequence from sequence.
Definition bdlat_symbolicconverter.h:764
static int convert(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlat_symbolicconverter.h:1350
int resolveDynamicTypes(LHS_TYPE *lhs, bdlat_TypeCategory::DynamicType lhsCategory, const RHS_TYPE &rhs, bdlat_TypeCategory::DynamicType rhsCategory)
Resolve dynamic types.
Definition bdlat_symbolicconverter.h:1010
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1404
static int accessByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_typecategory.h:1444
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *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 manipulateSelection(TYPE *object, MANIPULATOR &manipulator)
int makeSelection(TYPE *object, int selectionId)
int accessSelection(const TYPE &object, ACCESSOR &accessor)
@ k_UNDEFINED_SELECTION_ID
Definition bdlat_choicefunctions.h:511
int selectionId(const TYPE &object)
const BaseType< TYPE >::Type & convertToBaseType(const TYPE &object)
int convertFromBaseType(TYPE *object, const BASE_TYPE &value)
int fromString(TYPE *result, const char *string, int stringLength)
void toString(bsl::string *result, const TYPE &value)
bool isNull(const TYPE &object)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
int accessValue(const TYPE &object, ACCESSOR &accessor)
void makeValue(TYPE *object)
int accessAttributes(const TYPE &object, ACCESSOR &accessor)
int manipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
StringRefImp< char > StringRef
Definition bslstl_stringref.h:699
TYPE::BaseType Type
Definition bdlat_customizedtypefunctions.h:536
Component-private struct. Do not use.
Definition bdlat_symbolicconverter.h:721
const RHS_TYPE * d_rhs_p
Definition bdlat_symbolicconverter.h:725
int operator()(TYPE *object, ANY_CATEGORY category)
Definition bdlat_symbolicconverter.h:743
bdlat_SymbolicConverter_Imp * d_instance_p
Definition bdlat_symbolicconverter.h:724
int operator()(TYPE *, bslmf::Nil)
Definition bdlat_symbolicconverter.h:735
Component-private struct. Do not use.
Definition bdlat_symbolicconverter.h:684
bdlat_SymbolicConverter_Imp * d_instance_p
Definition bdlat_symbolicconverter.h:687
int operator()(const TYPE &object, ANY_CATEGORY category)
Definition bdlat_symbolicconverter.h:706
int operator()(const TYPE &, bslmf::Nil)
Definition bdlat_symbolicconverter.h:698
LHS_TYPE * d_lhs_p
Definition bdlat_symbolicconverter.h:688
Definition bdlat_symbolicconverter.h:292
Definition bdlat_typecategory.h:1035
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1034
Definition bdlat_typecategory.h:1038
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1040
Definition bdlat_typecategory.h:1041
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131