iterator_traits.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Copyright 2016-2017 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.
  25. */
  26. template<typename Iterator>
  27. struct poly_collection_of /* to be specialized for iterator impls */
  28. {
  29. using type=void;
  30. };
  31. template<typename PolyCollection>
  32. struct model_of;
  33. template<typename Model,typename Allocator>
  34. struct model_of<common_impl::poly_collection<Model,Allocator>>
  35. {
  36. using type=Model;
  37. };
  38. template<typename Iterator>
  39. struct iterator_traits
  40. {
  41. using container_type=typename poly_collection_of<Iterator>::type;
  42. using is_const_iterator=typename std::is_const<
  43. typename std::remove_reference<
  44. typename std::iterator_traits<Iterator>::reference
  45. >::type
  46. >::type;
  47. using iterator=typename std::conditional<
  48. is_const_iterator::value,
  49. typename container_type::const_iterator,
  50. typename container_type::iterator
  51. >::type;
  52. using base_segment_info_iterator=typename std::conditional<
  53. is_const_iterator::value,
  54. typename container_type::const_base_segment_info_iterator,
  55. typename container_type::base_segment_info_iterator
  56. >::type;
  57. using local_base_iterator=typename std::conditional<
  58. is_const_iterator::value,
  59. typename container_type::const_local_base_iterator,
  60. typename container_type::local_base_iterator
  61. >::type;
  62. template<typename T>
  63. using local_iterator=typename std::conditional<
  64. is_const_iterator::value,
  65. typename container_type::template const_local_iterator<T>,
  66. typename container_type::template local_iterator<T>
  67. >::type;
  68. static base_segment_info_iterator
  69. base_segment_info_iterator_from(iterator it)noexcept{return it.mapit;}
  70. static base_segment_info_iterator
  71. base_segment_info_iterator_from(local_base_iterator it)noexcept
  72. {return it.mapit;}
  73. static base_segment_info_iterator
  74. end_base_segment_info_iterator_from(iterator it)noexcept{return it.mapend;}
  75. static local_base_iterator
  76. local_base_iterator_from(iterator it)noexcept
  77. {
  78. return {
  79. it.mapit,
  80. model_of<container_type>::type::nonconst_iterator(it.segpos)
  81. };
  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. };
  90. } /* namespace poly_collection::detail */
  91. } /* namespace poly_collection */
  92. } /* namespace boost */
  93. #endif