1 // Copyright (C) 2019 T. Zachary Laine 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 #ifndef BOOST_STL_INTERFACES_FWD_HPP 7 #define BOOST_STL_INTERFACES_FWD_HPP 8 9 #include <iterator> 10 11 #ifndef BOOST_STL_INTERFACES_DOXYGEN 12 13 #if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8 14 #define BOOST_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR 15 #define BOOST_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR 16 #else 17 #define BOOST_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr 18 #endif 19 20 #if defined(__GNUC__) && __GNUC__ < 9 21 #define BOOST_STL_INTERFACES_CONCEPT concept bool 22 #else 23 #define BOOST_STL_INTERFACES_CONCEPT concept 24 #endif 25 26 #endif 27 28 29 namespace boost { namespace stl_interfaces { 30 inline namespace v1 { 31 32 /** An enumeration used to indicate whether the underlying data have a 33 contiguous or discontiguous layout when instantiating 34 `view_interface` and `sequence_container_interface`. */ 35 enum class element_layout : bool { 36 discontiguous = false, 37 contiguous = true 38 }; 39 40 namespace v1_dtl { 41 template<typename... T> 42 using void_t = void; 43 44 template<typename Iter> 45 using iter_difference_t = 46 typename std::iterator_traits<Iter>::difference_type; 47 48 template<typename Range, typename = void> 49 struct iterator; 50 template<typename Range> 51 struct iterator< 52 Range, 53 void_t<decltype(std::declval<Range &>().begin())>> 54 { 55 using type = decltype(std::declval<Range &>().begin()); 56 }; 57 template<typename Range> 58 using iterator_t = typename iterator<Range>::type; 59 60 template<typename Range, typename = void> 61 struct sentinel; 62 template<typename Range> 63 struct sentinel< 64 Range, 65 void_t<decltype(std::declval<Range &>().end())>> 66 { 67 using type = decltype(std::declval<Range &>().end()); 68 }; 69 template<typename Range> 70 using sentinel_t = typename sentinel<Range>::type; 71 72 template<typename Range> 73 using range_difference_t = iter_difference_t<iterator_t<Range>>; 74 75 template<typename Range> 76 using common_range = 77 std::is_same<iterator_t<Range>, sentinel_t<Range>>; 78 79 template<typename Range, typename = void> 80 struct decrementable_sentinel : std::false_type 81 { 82 }; 83 template<typename Range> 84 struct decrementable_sentinel< 85 Range, 86 void_t<decltype(--std::declval<sentinel_t<Range> &>())>> 87 : std::true_type 88 { 89 }; 90 } 91 92 } 93 }} 94 95 #endif 96