1 /*
2 
3 Copyright (c) 2002-2008, Yauheni Akhotnikau
4 Copyright (c) 2008-2016, The SObjectizer Project
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 - Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12 
13 - Redistributions in binary form must reproduce the above copyright notice, this
14 list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16 
17 - The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29 OF SUCH DAMAGE.
30 
31 */
32 
33 /*!
34 	\file
35 	\brief Interfaces for various parts of scheme.
36 */
37 
38 #if !defined( OESS_2_SCHEME_TYPES_HPP )
39 #define OESS_2_SCHEME_TYPES_HPP
40 
41 #include <exception>
42 #include <iterator>
43 #include <vector>
44 #include <string>
45 
46 #include <oess_2/scheme/h/declspec.hpp>
47 
48 #include <cpp_util_2/h/nocopy.hpp>
49 
50 #include <oess_2/defs/h/types.hpp>
51 
52 #include <oess_2/stdsn/type_tag/h/type_tag.hpp>
53 
54 namespace oess_2 {
55 
56 namespace scheme {
57 
58 //
59 // type_id_value_t
60 //
61 /*!
62  * \since v.2.1.0
63  * \brief Typedef for OID value representation.
64  */
65 typedef oess_2::stdsn::type_tag::type_tag_t::raw_type_id_value_t
66 		type_id_value_t;
67 
68 class	type_t;
69 
70 //
71 // packing_format_t
72 //
73 /*!
74  * \since v.2.1.0
75  * \brief Type of object dimension representation format.
76  */
77 enum packing_format_t
78 {
79 	//! Old fixed-width representation.
80 	OESS_1_FIXED_SIZE_FORMAT,
81 	//! Version 2.0/2.1 variable-width representation.
82 	OESS_2_VARIABLE_SIZE_FORMAT
83 };
84 
85 //
86 // base_t
87 //
88 
89 /*!
90 	\brief Interace of base type.
91 */
92 class	OESS_2_SCHEME_TYPE	base_t
93 {
94 	public :
95 		virtual ~base_t();
96 
97 		virtual const type_t &
98 		query_type() const = 0;
99 
100 		virtual bool
101 		is_virtual() const = 0;
102 
103 		virtual bool
104 		is_extension_of() const = 0;
105 };
106 
107 //
108 // cpp_mapping_t
109 //
110 
111 /*!
112 	\brief Interface of C++ mapping description.
113 */
114 class	OESS_2_SCHEME_TYPE	cpp_mapping_t {
115 	public :
116 		virtual ~cpp_mapping_t();
117 
118 		//! Name of the type in C++.
119 		/*!
120 		 * If that name is not defined in type description a name of
121 		 * type from DDL is returned.
122 		 */
123 		virtual const std::string &
124 		query_name() const = 0;
125 };
126 
127 //
128 // container_info_t
129 //
130 /*!
131  * \since v.2.1.0
132  * \brief Description of container type and representation format.
133  *
134  * This type is used in v.2.1.0 instead of old attr_cont_kind_t.
135  */
136 class OESS_2_SCHEME_TYPE container_info_t
137 {
138 public :
139 	//! Type of container.
140 	enum variant_t
141 	{
142 		//! Attribute is not a container.
143 		NOT_CONTAINER,
144 		//! Attribute is a vector.
145 		VECTOR,
146 		//! Attribute is a list.
147 		LIST,
148 		//! Attribute is a deque.
149 		DEQUE,
150 		//! Attribute is a set (without duplicates).
151 		SET,
152 		//! Attribute is a multiset.
153 		MULTI_SET,
154 		//! Attribute is a map (without duplicates).
155 		MAP,
156 		//! Attribute is a multimap.
157 		MULTI_MAP,
158 		//! Attribute is a fixed size array.
159 		FIXED_SIZE_VECTOR
160 	};
161 
162 	//! What kind of container is?
163 	variant_t
164 	variant() const;
165 
166 	//! What is packing format for container size?
167 	packing_format_t
168 	packing_format() const;
169 
170 	//! What is dimension of fixed size vector?
171 	/*!
172 	 * \throw oess_2::ex_t if container is not a fixed size vector.
173 	 */
174 	size_t
175 	fixed_size_vector_dimension() const;
176 
177 	//! What is a key type for map or multimap?
178 	/*!
179 	 * \throw oess_2::ex_t if container is not a map or multimap.
180 	 */
181 	const type_t &
182 	map_key_type() const;
183 
184 	//! Construct as not a container.
185 	static container_info_t
186 	make_as_not_container();
187 
188 	//! Construct as ordinal container.
189 	static container_info_t
190 	make_as_ordinal(
191 		variant_t container_type,
192 		packing_format_t packing_format );
193 
194 	//! Construct as map.
195 	static container_info_t
196 	make_as_map(
197 		const type_t & key_type,
198 		packing_format_t packing_format );
199 
200 	//! Construct as multimap.
201 	static container_info_t
202 	make_as_multimap(
203 		const type_t & key_type,
204 		packing_format_t packing_format );
205 
206 	//! Construct as fixed size vector.
207 	static container_info_t
208 	make_as_fixed_size_vector(
209 		size_t dimension );
210 
211 private :
212 	//! Variant of a container.
213 	variant_t m_variant;
214 
215 	//! Packing format for container type.
216 	packing_format_t m_packing_format;
217 
218 	//! Key type for a map/multimap.
219 	const type_t * m_map_key_type;
220 
221 	//! Dimension for a fixed size vector.
222 	size_t m_fixed_size_vector_dimension;
223 
224 	//! Constructor.
225 	container_info_t(
226 		variant_t variant,
227 		packing_format_t packing_format,
228 		const type_t * map_key_type,
229 		size_t fixed_size_vector_dimension );
230 };
231 
232 //
233 // attr_type_t
234 //
235 
236 /*!
237  * \brief Interface for description of attribute's type.
238 */
239 class	OESS_2_SCHEME_TYPE	attr_type_t {
240 	public :
241 		virtual ~attr_type_t();
242 
243 		virtual const type_t &
244 		query_type() const = 0;
245 
246 		//! Kind of attribute type.
247 		enum type_kind_t {
248 			//! Attribute is an object.
249 			VALUE,
250 			//! Attribute is a pointer.
251 			PTR,
252 			//! Attribute is a pointer to extension.
253 			EXTENSION
254 		};
255 
256 		virtual type_kind_t
257 		query_type_kind() const = 0;
258 
259 		virtual const container_info_t &
260 		query_container_info() const = 0;
261 };
262 
263 //
264 // attr_present_if_t
265 //
266 
267 /*!
268 	\since
269 	v.1.2.0
270 	\brief Interface for serialization predicate for optional attribute.
271 */
272 class	attr_present_if_t
273 :	private cpp_util_2::nocopy_t
274 {
275 	public :
276 		virtual ~attr_present_if_t();
277 
278 		//! Get predicate for C++.
279 		/*!
280 			\throw std::exception if there is no predicate for C++.
281 		*/
282 		virtual const std::string &
283 		cpp() const = 0;
284 
285 		//! Is there a predicate for C++?
286 		virtual bool
287 		is_cpp() const = 0;
288 };
289 
290 //
291 // attr_default_t
292 //
293 
294 /*!
295 	\since
296 	v.1.2.0
297 	\brief Interface for default value of attribute.
298 */
299 class	attr_default_t
300 :	private cpp_util_2::nocopy_t
301 {
302 	public :
303 		virtual ~attr_default_t();
304 
305 		//! Get default value for C++.
306 		virtual const std::string &
307 		cpp() const = 0;
308 
309 		//! Is there default value for C++?
310 		virtual bool
311 		is_cpp() const = 0;
312 
313 		//! Is it attribute optional?
314 		virtual bool
315 		is_optional() const = 0;
316 
317 		//! Get serialization predicate.
318 		/*!
319 			\throw std::exception If attribute is not optional.
320 		*/
321 		virtual const attr_present_if_t &
322 		present_if() const = 0;
323 };
324 
325 //
326 // attr_t
327 //
328 
329 /*!
330 	\brief Interface of attribute.
331 */
332 class	OESS_2_SCHEME_TYPE	attr_t {
333 	public :
334 		virtual ~attr_t();
335 
336 		//! Attribute name.
337 		virtual const std::string &
338 		query_name() const = 0;
339 
340 		//! Attribute type.
341 		virtual const attr_type_t &
342 		query_attr_type() const = 0;
343 
344 		/*!
345 			\since
346 			v.1.2.0
347 			\brief Get default value.
348 			\return 0, if default value is not specified.
349 		*/
350 		virtual const attr_default_t *
351 		query_attr_default() const = 0;
352 
353 		/*!
354 		 * \since
355 		 * v.2.1.0
356 		 * \brief Helper method to check optionallity of attribute.
357 		 */
358 		inline bool
is_optional() const359 		is_optional() const {
360 			return ( this->query_attr_default() &&
361 				this->query_attr_default()->is_optional() );
362 		}
363 
364 		/*!
365 			\since
366 			v.1.2.0
367 			\brief Extension level to which the attribute belongs.
368 
369 			\return 0, if attribute is not part of extension.
370 		*/
371 		virtual size_t
372 		extension_level() const = 0;
373 };
374 
375 //
376 // type_t
377 //
378 
379 /*!
380 	\brief Interface of type.
381 */
382 class	OESS_2_SCHEME_TYPE	type_t {
383 	public :
384 		virtual ~type_t();
385 
386 		//! Name of type.
387 		virtual const std::string &
388 		query_name() const = 0;
389 
390 		//! Is type completely defined?
391 		virtual bool
392 		is_defined() const = 0;
393 
394 		//! Is type a builtin type?
395 		virtual bool
396 		is_builtin() const = 0;
397 
398 		//! Is abstract type?
399 		virtual bool
400 		is_abstract() const = 0;
401 
402 		/*!
403 			\since
404 			v.1.2.0
405 			\brief Is extensible?
406 		*/
407 		virtual bool
408 		is_extensible() const = 0;
409 
410 		/*!
411 			\since
412 			v.1.2.0
413 			\brief Is subclassing_by_extension supported?
414 		*/
415 		virtual bool
416 		is_subclassing_by_extension() const = 0;
417 
418 		/*!
419 			\since
420 			v.1.2.0
421 			\brief Is this type derived as extension of supertype?
422 
423 			\return true, is subclassing_by_extension was used and
424 				this type is derived as extension of supertype.
425 		*/
426 		virtual bool
427 		is_derived_as_extension() const = 0;
428 
429 		/*!
430 			\since
431 			v.2.1.0
432 			\brief Has numeric type ID?
433 		*/
434 		virtual bool
435 		has_type_id() const = 0;
436 
437 		/*!
438 			\since
439 			v.2.0.0
440 			\brief Does this type use bitmask for optional attributes?
441 		*/
442 		virtual bool
443 		does_use_bitmask() const = 0;
444 
445 		//! Total count of bases.
446 		virtual size_t
447 		query_base_count() const = 0;
448 
449 		//! Get a base type by index.
450 		/*!
451 		 * Indexing is started from 0.
452 		 */
453 		virtual const base_t &
454 		query_base( size_t index ) const = 0;
455 
456 		//! Find a base by name.
457 		/*!
458 		 * \return 0 if base is not found.
459 		 */
460 		virtual const base_t *
461 		find_base( const std::string & name ) const = 0;
462 
463 		//! Get the total count of attributes.
464 		/*!
465 		 * \note All attributes in all extensions are counted.
466 		 * \sa extension_attr_count(), extension_attr().
467 		 */
468 		virtual size_t
469 		query_attr_count() const = 0;
470 
471 		//! Access to attribute by its ordinal number.
472 		/*!
473 		 * Attribute indexing is started from 0.
474 		 *
475 		 * \note This method gives access to list of all attributes.
476 		 * All attributes from all extensions are parts of this list.
477 		 * For access to attributes from a particular extension
478 		 * extension_attr_count() and extension_attr() methods should be
479 		 * used.
480 		 */
481 		virtual const attr_t &
482 		query_attr( size_t index ) const = 0;
483 
484 		//! Find attribute by name.
485 		/*!
486 		 * \return 0 if attribute is not found.
487 		 */
488 		virtual const attr_t *
489 		find_attr( const std::string & name ) const = 0;
490 
491 		//! Get C++ mapping.
492 		virtual const cpp_mapping_t &
493 		query_cpp_mapping() const = 0;
494 
495 		//! The deep of extensions for type.
496 		/*!
497 		 * \since
498 		 * v.1.2.0
499 		 *
500 		 * \return 0 if type has no extension. 1 if there is only
501 		 * one extension. 2 if there are two extensions and so on.
502 		 */
503 		virtual size_t
504 		extension_deep() const = 0;
505 
506 		//! Number of attributes in a particular extensions.
507 		/*!
508 		 * \since
509 		 * v.1.2.0
510 		 *
511 		 * If extension == 0 then the number of attributes outside of any
512 		 * extension is returned.
513 		 */
514 		virtual size_t
515 		extension_attr_count( size_t extension ) const = 0;
516 
517 		//! Get attribute in a particular extension.
518 		/*!
519 		 * \since v.1.2.0
520 		 *
521 		 * If extension == 0 then an attribute which is not part of any
522 		 * extension is returned.
523 		 */
524 		virtual const attr_t &
525 		extension_attr( size_t extension,
526 			size_t attr_index ) const = 0;
527 
528 		/*!
529 			\since
530 			v.2.1.0
531 			\brief Read-only access to type_id.
532 		*/
533 		virtual const type_id_value_t &
534 		query_type_id() const = 0;
535 
536 		/*!
537 			\since
538 			v.2.1.0
539 			\brief Change type_id.
540 		*/
541 		virtual void
542 		set_type_id( type_id_value_t && type_id ) = 0;
543 
544 		/*!
545 		 * \since
546 		 * v.2.1.0
547 		 * \brief Get type_tag for type.
548 		 */
549 		virtual oess_2::stdsn::type_tag::type_tag_t
550 		query_type_tag() const = 0;
551 
552 		/*!
553 		 * \since
554 		 * v.2.1.0
555 		 * \brief Get packing format for type.
556 		 */
557 		virtual packing_format_t
558 		query_packing_format() const = 0;
559 };
560 
561 //
562 // pseudo_base_list_t
563 //
564 
565 /*!
566 	\brief Representation of base type list in STL-containers style.
567 */
568 class	pseudo_base_list_t {
569 	private :
570 		const type_t &	m_type;
571 
572 	public :
573 		inline
pseudo_base_list_t(const type_t & t)574 		pseudo_base_list_t( const type_t & t ) :
575 			m_type( t )
576 		{}
577 
578 		class	const_iterator
579 			:	public std::iterator< std::forward_iterator_tag, base_t > {
580 			friend class pseudo_base_list_t;
581 			private :
582 				const type_t *	m_type;
583 				size_t	m_index;
584 
585 				inline
const_iterator(const type_t & t,size_t index)586 				const_iterator(
587 					const type_t & t,
588 					size_t index ) :
589 					m_type( &t ),
590 					m_index( index )
591 				{
592 				}
593 
594 			public :
595 				inline
const_iterator()596 				const_iterator() :
597 					m_type( 0 ),
598 					m_index( 0 )
599 				{
600 				}
601 
602 				inline
const_iterator(const const_iterator & o)603 				const_iterator(
604 					const const_iterator & o ) :
605 					m_type( o.m_type ),
606 					m_index( o.m_index )
607 				{
608 				}
609 
610 				inline const base_t &
operator *() const611 				operator*() const {
612 					return m_type->query_base( m_index );
613 				}
614 
615 				bool
operator ==(const const_iterator & o) const616 				operator==( const const_iterator & o ) const {
617 					return ( m_type == o.m_type && m_index == o.m_index );
618 				}
619 
620 				bool
operator !=(const const_iterator & o) const621 				operator!=( const const_iterator & o ) const {
622 					return ( m_type != o.m_type || m_index != o.m_index );
623 				}
624 
625 				const_iterator&
operator ++()626 				operator++() {
627 					++m_index;
628 					return *this;
629 				}
630 
631 				const_iterator
operator ++(int)632 				operator++( int ) {
633 					return const_iterator( *m_type, m_index++ );
634 				}
635 		};
636 
637 		inline const_iterator
begin() const638 		begin() const {
639 			return const_iterator( m_type, 0 );
640 		}
641 
642 		inline const_iterator
end() const643 		end() const {
644 			return const_iterator( m_type, m_type.query_base_count() );
645 		}
646 };
647 
648 //
649 // pseudo_attr_list_t
650 //
651 /*!
652 	\brief Representation of attribute list in STL-containers style.
653 */
654 class	pseudo_attr_list_t {
655 	private :
656 		const type_t &	m_type;
657 
658 	public :
659 		inline
pseudo_attr_list_t(const type_t & t)660 		pseudo_attr_list_t( const type_t & t )
661 			:	m_type( t )
662 		{}
663 
664 		class	const_iterator
665 			: public std::iterator< std::forward_iterator_tag, attr_t > {
666 			friend class pseudo_attr_list_t;
667 			private :
668 				const type_t *	m_type;
669 				size_t	m_index;
670 
671 				inline
const_iterator(const type_t & t,size_t index)672 				const_iterator(
673 					const type_t & t,
674 					size_t index ) :
675 					m_type( &t ),
676 					m_index( index )
677 				{
678 				}
679 
680 			public :
681 				inline
const_iterator()682 				const_iterator() : m_type( 0 ), m_index( 0 )
683 				{
684 				}
685 
686 				inline
const_iterator(const const_iterator & o)687 				const_iterator(
688 					const const_iterator & o ) :
689 					m_type( o.m_type ),
690 					m_index( o.m_index )
691 				{
692 				}
693 
694 				inline const attr_t &
operator *() const695 				operator*() const {
696 					return m_type->query_attr( m_index );
697 				}
698 
699 				bool
operator ==(const const_iterator & o) const700 				operator==( const const_iterator & o ) const {
701 					return ( m_type == o.m_type && m_index == o.m_index );
702 				}
703 
704 				bool
operator !=(const const_iterator & o) const705 				operator!=( const const_iterator & o ) const {
706 					return ( m_type != o.m_type || m_index != o.m_index );
707 				}
708 
709 				const_iterator&
operator ++()710 				operator++() {
711 					++m_index;
712 					return *this;
713 				}
714 
715 				const_iterator
operator ++(int)716 				operator++( int ) {
717 					return const_iterator( *m_type, m_index++ );
718 				}
719 		};
720 
721 		inline const_iterator
begin() const722 		begin() const {
723 			return const_iterator( m_type, 0 );
724 		}
725 
726 		inline const_iterator
end() const727 		end() const {
728 			return const_iterator( m_type, m_type.query_attr_count() );
729 		}
730 };
731 
732 //
733 // pseudo_extension_attr_list_t
734 //
735 
736 /*!
737  * \since
738  * v.1.2.0
739  * \brief A list of attributes in STL-containers style.
740  *
741  * If extension==0 in the constructor then all attributes which are
742  * not parts of any extension are enumerated.
743  */
744 class	pseudo_extension_attr_list_t {
745 	private :
746 		const type_t &	m_type;
747 		const size_t	m_extension;
748 
749 	public :
750 		inline
pseudo_extension_attr_list_t(const type_t & t,size_t extension)751 		pseudo_extension_attr_list_t(
752 			const type_t & t,
753 			size_t extension )
754 		:	m_type( t )
755 		,	m_extension( extension )
756 		{}
757 
758 		class	const_iterator
759 			: public std::iterator< std::forward_iterator_tag, attr_t >
760 		{
761 			friend class pseudo_extension_attr_list_t;
762 			private :
763 				const type_t *	m_type;
764 				const size_t m_extension;
765 				size_t	m_index;
766 
767 				inline
const_iterator(const type_t & t,const size_t extension,size_t index)768 				const_iterator(
769 					const type_t & t,
770 					const size_t extension,
771 					size_t index )
772 				:	m_type( &t )
773 				,	m_extension( extension )
774 				,	m_index( index )
775 				{}
776 
777 			public :
778 				inline
const_iterator()779 				const_iterator()
780 				:	m_type( 0 )
781 				,	m_extension( 0 )
782 				,	m_index( 0 )
783 				{}
784 
785 				inline
const_iterator(const const_iterator & o)786 				const_iterator(
787 					const const_iterator & o )
788 				:	m_type( o.m_type )
789 				,	m_extension( o.m_extension )
790 				,	m_index( o.m_index )
791 				{}
792 
793 				inline const attr_t &
operator *() const794 				operator*() const
795 				{
796 					return m_type->extension_attr(
797 						m_extension, m_index );
798 				}
799 
800 				bool
operator ==(const const_iterator & o) const801 				operator==( const const_iterator & o ) const
802 				{
803 					return ( m_type == o.m_type &&
804 						m_extension == o.m_extension &&
805 						m_index == o.m_index );
806 				}
807 
808 				bool
operator !=(const const_iterator & o) const809 				operator!=( const const_iterator & o ) const
810 				{
811 					return ( m_type != o.m_type ||
812 						m_extension != o.m_extension ||
813 						m_index != o.m_index );
814 				}
815 
816 				const_iterator&
operator ++()817 				operator++()
818 				{
819 					++m_index;
820 					return *this;
821 				}
822 
823 				const_iterator
operator ++(int)824 				operator++( int )
825 				{
826 					return const_iterator( *m_type,
827 						m_extension, m_index++ );
828 				}
829 		};
830 
831 		inline const_iterator
begin() const832 		begin() const
833 		{
834 			return const_iterator( m_type, m_extension, 0 );
835 		}
836 
837 		inline const_iterator
end() const838 		end() const
839 		{
840 			return const_iterator( m_type, m_extension,
841 				m_type.extension_attr_count( m_extension ) );
842 		}
843 };
844 
845 } /* scheme */
846 
847 } /* namespace oess_2 */
848 
849 #endif
850 
851