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