iterator_traits.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* Copyright 2016-2024 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/poly_collection for library home page.
  7. */
  8. #ifndef BOOST_POLY_COLLECTION_DETAIL_ITERATOR_TRAITS_HPP
  9. #define BOOST_POLY_COLLECTION_DETAIL_ITERATOR_TRAITS_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <iterator>
  14. #include <type_traits>
  15. namespace boost{
  16. namespace poly_collection{
  17. namespace common_impl{
  18. template<typename Model,typename Allocator>
  19. class poly_collection;
  20. }
  21. namespace detail{
  22. /* (Internal) bunch of traits-grouped functions for const-preserving
  23. * interoperatibility between iterators and local iterators of a
  24. * poly_collection, plus access to associated model's index from
  25. * an iterator type.
  26. */
  27. template<typename Iterator>
  28. struct poly_collection_of /* to be specialized for iterator impls */
  29. {
  30. using type=void;
  31. };
  32. template<typename PolyCollection>
  33. struct model_of;
  34. template<typename Model,typename Allocator>
  35. struct model_of<common_impl::poly_collection<Model,Allocator>>
  36. {
  37. using type=Model;
  38. };
  39. template<typename Iterator>
  40. struct iterator_traits
  41. {
  42. using container_type=typename poly_collection_of<Iterator>::type;
  43. using model_type=typename model_of<container_type>::type;
  44. using type_index=typename container_type::type_index;
  45. using is_const_iterator=typename std::is_const<
  46. typename std::remove_reference<
  47. typename std::iterator_traits<Iterator>::reference
  48. >::type
  49. >::type;
  50. using iterator=typename std::conditional<
  51. is_const_iterator::value,
  52. typename container_type::const_iterator,
  53. typename container_type::iterator
  54. >::type;
  55. using base_segment_info_iterator=typename std::conditional<
  56. is_const_iterator::value,
  57. typename container_type::const_base_segment_info_iterator,
  58. typename container_type::base_segment_info_iterator
  59. >::type;
  60. using local_base_iterator=typename std::conditional<
  61. is_const_iterator::value,
  62. typename container_type::const_local_base_iterator,
  63. typename container_type::local_base_iterator
  64. >::type;
  65. template<typename T>
  66. using local_iterator=typename std::conditional<
  67. is_const_iterator::value,
  68. typename container_type::template const_local_iterator<T>,
  69. typename container_type::template local_iterator<T>
  70. >::type;
  71. static base_segment_info_iterator
  72. base_segment_info_iterator_from(iterator it)noexcept{return it.mapit;}
  73. static base_segment_info_iterator
  74. base_segment_info_iterator_from(local_base_iterator it)noexcept
  75. {return it.mapit;}
  76. static base_segment_info_iterator
  77. end_base_segment_info_iterator_from(iterator it)noexcept{return it.mapend;}
  78. static local_base_iterator
  79. local_base_iterator_from(iterator it)noexcept
  80. {
  81. return {it.mapit,model_type::nonconst_iterator(it.segpos)};
  82. }
  83. static iterator
  84. iterator_from(
  85. local_base_iterator lbit,base_segment_info_iterator mapend)noexcept
  86. {
  87. return {lbit.mapit,mapend.base(),lbit.base()};
  88. }
  89. template<typename T>
  90. static decltype(model_type::template index<T>()) index()
  91. {
  92. return model_type::template index<T>();
  93. }
  94. };
  95. } /* namespace poly_collection::detail */
  96. } /* namespace poly_collection */
  97. } /* namespace boost */
  98. #endif