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     {
length(const char * s)37         inline std::size_t length( const char* s )
38         {
39             return strlen( s );
40         }
41 
42 #ifndef BOOST_NO_CXX11_CHAR16_T
length(const char16_t * s)43         inline std::size_t length( const char16_t* s )
44         {
45             return std::char_traits<char16_t>::length( s );
46         }
47 #endif
48 
49 #ifndef BOOST_NO_CXX11_CHAR32_T
length(const char32_t * s)50         inline std::size_t length( const char32_t* s )
51         {
52             return std::char_traits<char32_t>::length( s );
53         }
54 #endif
55 
56 #ifndef BOOST_NO_CWCHAR
length(const wchar_t * s)57         inline std::size_t length( const wchar_t* s )
58         {
59             return wcslen( 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 
is_char_ptr(char *)69         inline bool is_char_ptr( char* )
70         {
71             return true;
72         }
73 
is_char_ptr(const char *)74         inline bool is_char_ptr( const char* )
75         {
76             return true;
77         }
78 
79 #ifndef BOOST_NO_CXX11_CHAR16_T
is_char_ptr(char16_t *)80         inline bool is_char_ptr( char16_t* )
81         {
82             return true;
83         }
84 
is_char_ptr(const char16_t *)85         inline bool is_char_ptr( const char16_t* )
86         {
87             return true;
88         }
89 #endif
90 
91 #ifndef BOOST_NO_CXX11_CHAR32_T
is_char_ptr(char32_t *)92         inline bool is_char_ptr( char32_t* )
93         {
94             return true;
95         }
96 
is_char_ptr(const char32_t *)97         inline bool is_char_ptr( const char32_t* )
98         {
99             return true;
100         }
101 #endif
102 
103 #ifndef BOOST_NO_CWCHAR
is_char_ptr(wchar_t *)104         inline bool is_char_ptr( wchar_t* )
105         {
106             return true;
107         }
108 
is_char_ptr(const wchar_t *)109         inline bool is_char_ptr( const wchar_t* )
110         {
111             return true;
112         }
113 #endif
114 
115         template< class T >
is_char_ptr(const 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*>
make_range(T * const r,bool)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>
make_range(T & r,long)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>
as_literal(Range & r)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>
as_literal(const Range & r)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 >
as_literal(Char (& arr)[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 >
as_literal(const Char (& arr)[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