[/
  Copyright 2016-2017 Joaquin M Lopez Munoz.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt)
]

[template poly_collection_synopsis[class_name template_header value_type]
  ``[template_header]``
  class ``[class_name]``
  {
  public:
    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.types ['// types:]]``

    using value_type=``[value_type]``;
    using allocator_type=Allocator;
    using size_type=std::size_t;
    using difference_type=std::ptrdiff_t;
    using reference=value_type&;
    using const_reference=const value_type&;
    using pointer=typename std::allocator_traits<Allocator>::pointer;
    using const_pointer=typename std::allocator_traits<Allocator>::const_pointer;
    using iterator=``/implementation-defined/``;
    using const_iterator=``/implementation-defined/``;
    using _local_base_iterator_=``/implementation-defined/``;
    using _const_local_base_iterator_=``/implementation-defined/``;
    template<typename T> using _local_iterator_=``/implementation-defined/``;
    template<typename T> using _const_local_iterator_=``/implementation-defined/``;
    class _const_base_segment_info_;
    class _base_segment_info_;
    template<typename T> class _const_segment_info_;
    template<typename T> class _segment_info_;
    using _base_segment_info_iterator_=``/implementation-defined/``;
    using _const_base_segment_info_iterator_=``/implementation-defined/``;
    class _const_segment_traversal_info_;
    class _segment_traversal_info_;

    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.construct_copy_destroy ['// construct/destroy/copy:]]``

    ``[class_name]``();
    ``[class_name]``(const ``[class_name]``&);
    ``[class_name]``(``[class_name]``&&);
    explicit ``[class_name]``(const allocator_type& al);
    ``[class_name]``(const ``[class_name]``& x,const allocator_type& al);
    ``[class_name]``(``[class_name]``&& x,const allocator_type& al);
    template<typename InputIterator>
    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.construct_copy_destroy.range_construction [class_name]]``(
      InputIterator first,InputIterator last,
      const allocator_type& al=allocator_type{});

    ``[class_name]``& operator=(const ``[class_name]``&);
    ``[class_name]``& operator=(``[class_name]``&&);

    allocator_type get_allocator()const noexcept;

    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.type_registration ['// type registration:]]``

    template<typename... T>
    void _register_types_();

    bool _is_registered_(const std::type_info& info)const;
    template<typename T> bool _is_registered_()const;

    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators ['// iterators:]]``

    iterator       _begin_()noexcept;
    iterator       _end_()noexcept;
    const_iterator _begin_()const noexcept;
    const_iterator _end_()const noexcept;
    const_iterator _cbegin_()const noexcept;
    const_iterator _cend_()const noexcept;

    local_base_iterator _begin_(const std::type_info& info);
    local_base_iterator _end_(const std::type_info& info);
    const_local_base_iterator _begin_(const std::type_info& info)const;
    const_local_base_iterator _end_(const std::type_info& info)const;
    const_local_base_iterator _cbegin_(const std::type_info& info)const;
    const_local_base_iterator _cend_(const std::type_info& info)const;

    template<typename T> local_iterator<T> _begin_();
    template<typename T> local_iterator<T> _end_();
    template<typename T> const_local_iterator<T> _begin_()const;
    template<typename T> const_local_iterator<T> _end_()const;
    template<typename T> const_local_iterator<T> _cbegin_()const;
    template<typename T> const_local_iterator<T> _cend_()const;

    base_segment_info       _segment_(const std::type_info& info);
    const_base_segment_info _segment_(const std::type_info& info)const;
    template<typename T> segment_info<T>       _segment_();
    template<typename T> const_segment_info<T> _segment_()const;

    segment_traversal_info       _segment_traversal_()noexcept;
    const_segment_traversal_info _segment_traversal_()const noexcept;

    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity ['// capacity:]]``

    bool empty()const noexcept;
    bool _empty_(const std::type_info& info)const;
    template<typename T> bool _empty_()const;

    size_type size()const noexcept;
    size_type _size_(const std::type_info& info)const;
    template<typename T> size_type _size_()const;

    size_type _max_size_(const std::type_info& info)const;
    template<typename T> size_type _max_size_()const;

    size_type _capacity_(const std::type_info& info)const;
    template<typename T> size_type _capacity_()const;

    void _reserve_(size_type n);
    void _reserve_(const std::type_info& info,size_type n);
    template<typename T>void _reserve_(size_type n);

    void _shrink_to_fit_();
    void _shrink_to_fit_(const std::type_info& info);
    template<typename T> void _shrink_to_fit_();

    ``[link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers ['// modifiers:]]``

    template<typename T,typename... Args>
    iterator _emplace_(Args&&... args);

    template<typename T,typename... Args>
    iterator _emplace_hint_(const_iterator hint,Args&&... args);

    template<typename T,typename LocalIterator,typename... Args>
    auto _emplace_pos_(LocalIterator pos,Args&&... args);

    template<typename T>
    iterator _insert_(T&& x);

    template<typename CollectionIterator,typename T>
    auto _insert_hint_(CollectionIterator hint,T&& x);

    template<typename InputIterator>
    void _insert_range_(InputIterator first,InputIterator last);

    template<typename CollectionIterator,typename InputIterator>
    void _insert_hint_range_(CollectionIterator hint,InputIterator first,InputIterator last);

    template<typename CollectionIterator>
    auto _erase_(CollectionIterator pos);

    template<typename CollectionIterator>
    auto _erase_(CollectionIterator first,CollectionIterator last);

    void _clear_()noexcept;
    void _clear_(const std::type_info& info);
    template<typename T> void _clear_();

    void swap(``[class_name]``& x);
  };
]