1 | // Boost.Range library |
2 | // |
3 | // Copyright Thorsten Ottosen 2006. Use, modification and |
4 | // distribution is subject to the Boost Software License, Version |
5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | // |
8 | // For more information, see http://www.boost.org/libs/range/ |
9 | // |
10 | |
11 | #ifndef BOOST_RANGE_AS_LITERAL_HPP |
12 | #define BOOST_RANGE_AS_LITERAL_HPP |
13 | |
14 | #if defined(_MSC_VER) |
15 | # pragma once |
16 | #endif |
17 | |
18 | #include <boost/range/iterator_range.hpp> |
19 | #include <boost/range/detail/str_types.hpp> |
20 | |
21 | #include <boost/detail/workaround.hpp> |
22 | |
23 | #include <cstring> |
24 | |
25 | #if !defined(BOOST_NO_CXX11_CHAR16_T) || !defined(BOOST_NO_CXX11_CHAR32_T) |
26 | #include <string> // for std::char_traits |
27 | #endif |
28 | |
29 | #ifndef BOOST_NO_CWCHAR |
30 | #include <cwchar> |
31 | #endif |
32 | |
33 | namespace boost |
34 | { |
35 | namespace range_detail |
36 | { |
37 | inline std::size_t length( const char* s ) |
38 | { |
39 | return strlen( s: s ); |
40 | } |
41 | |
42 | #ifndef BOOST_NO_CXX11_CHAR16_T |
43 | inline std::size_t length( const char16_t* s ) |
44 | { |
45 | return std::char_traits<char16_t>::length( s: s ); |
46 | } |
47 | #endif |
48 | |
49 | #ifndef BOOST_NO_CXX11_CHAR32_T |
50 | inline std::size_t length( const char32_t* s ) |
51 | { |
52 | return std::char_traits<char32_t>::length( s: s ); |
53 | } |
54 | #endif |
55 | |
56 | #ifndef BOOST_NO_CWCHAR |
57 | inline std::size_t length( const wchar_t* s ) |
58 | { |
59 | return wcslen( s: s ); |
60 | } |
61 | #endif |
62 | |
63 | // |
64 | // Remark: the compiler cannot choose between T* and T[sz] |
65 | // overloads, so we must put the T* internal to the |
66 | // unconstrained version. |
67 | // |
68 | |
69 | inline bool is_char_ptr( char* ) |
70 | { |
71 | return true; |
72 | } |
73 | |
74 | inline bool is_char_ptr( const char* ) |
75 | { |
76 | return true; |
77 | } |
78 | |
79 | #ifndef BOOST_NO_CXX11_CHAR16_T |
80 | inline bool is_char_ptr( char16_t* ) |
81 | { |
82 | return true; |
83 | } |
84 | |
85 | inline bool is_char_ptr( const char16_t* ) |
86 | { |
87 | return true; |
88 | } |
89 | #endif |
90 | |
91 | #ifndef BOOST_NO_CXX11_CHAR32_T |
92 | inline bool is_char_ptr( char32_t* ) |
93 | { |
94 | return true; |
95 | } |
96 | |
97 | inline bool is_char_ptr( const char32_t* ) |
98 | { |
99 | return true; |
100 | } |
101 | #endif |
102 | |
103 | #ifndef BOOST_NO_CWCHAR |
104 | inline bool is_char_ptr( wchar_t* ) |
105 | { |
106 | return true; |
107 | } |
108 | |
109 | inline bool is_char_ptr( const wchar_t* ) |
110 | { |
111 | return true; |
112 | } |
113 | #endif |
114 | |
115 | template< class T > |
116 | inline long is_char_ptr( const T& /* r */ ) |
117 | { |
118 | return 0L; |
119 | } |
120 | |
121 | template< class T > |
122 | inline iterator_range<T*> |
123 | make_range( T* const r, bool ) |
124 | { |
125 | return iterator_range<T*>( r, r + length(r) ); |
126 | } |
127 | |
128 | template< class T > |
129 | inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type> |
130 | make_range( T& r, long ) |
131 | { |
132 | return boost::make_iterator_range( r ); |
133 | } |
134 | |
135 | } |
136 | |
137 | template< class Range > |
138 | inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type> |
139 | as_literal( Range& r ) |
140 | { |
141 | return range_detail::make_range( r, range_detail::is_char_ptr(r) ); |
142 | } |
143 | |
144 | template< class Range > |
145 | inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type> |
146 | as_literal( const Range& r ) |
147 | { |
148 | return range_detail::make_range( r, range_detail::is_char_ptr(r) ); |
149 | } |
150 | |
151 | template< class Char, std::size_t sz > |
152 | inline iterator_range<Char*> as_literal( Char (&arr)[sz] ) |
153 | { |
154 | return range_detail::make_range( arr, range_detail::is_char_ptr(arr) ); |
155 | } |
156 | |
157 | template< class Char, std::size_t sz > |
158 | inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] ) |
159 | { |
160 | return range_detail::make_range( arr, range_detail::is_char_ptr(arr) ); |
161 | } |
162 | } |
163 | |
164 | #endif |
165 | |