1 // Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey 2 // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ 3 4 #ifndef TAO_PEGTL_MEMORY_INPUT_HPP 5 #define TAO_PEGTL_MEMORY_INPUT_HPP 6 7 #include <cstddef> 8 #include <cstring> 9 #include <string> 10 #include <type_traits> 11 #include <utility> 12 13 #include "config.hpp" 14 #include "eol.hpp" 15 #include "position.hpp" 16 #include "tracking_mode.hpp" 17 18 #include "internal/action_input.hpp" 19 #include "internal/bump_impl.hpp" 20 #include "internal/iterator.hpp" 21 #include "internal/marker.hpp" 22 23 namespace tao 24 { 25 namespace TAO_PEGTL_NAMESPACE 26 { 27 namespace internal 28 { 29 template< tracking_mode, typename Eol, typename Source > 30 class memory_input_base; 31 32 template< typename Eol, typename Source > 33 class memory_input_base< tracking_mode::IMMEDIATE, Eol, Source > 34 { 35 public: 36 using iterator_t = internal::iterator; 37 38 template< typename T > memory_input_base(const iterator_t & in_begin,const char * in_end,T && in_source)39 memory_input_base( const iterator_t& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 40 : m_current( in_begin ), 41 m_end( in_end ), 42 m_source( std::forward< T >( in_source ) ) 43 { 44 } 45 46 template< typename T > memory_input_base(const char * in_begin,const char * in_end,T && in_source)47 memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 48 : m_current( in_begin ), 49 m_end( in_end ), 50 m_source( std::forward< T >( in_source ) ) 51 { 52 } 53 54 memory_input_base( const memory_input_base& ) = delete; 55 memory_input_base( memory_input_base&& ) = delete; 56 57 ~memory_input_base() = default; 58 59 memory_input_base operator=( const memory_input_base& ) = delete; 60 memory_input_base operator=( memory_input_base&& ) = delete; 61 current() const62 const char* current() const noexcept 63 { 64 return m_current.data; 65 } 66 end(const std::size_t=0) const67 const char* end( const std::size_t /*unused*/ = 0 ) const noexcept 68 { 69 return m_end; 70 } 71 byte() const72 std::size_t byte() const noexcept 73 { 74 return m_current.byte; 75 } 76 line() const77 std::size_t line() const noexcept 78 { 79 return m_current.line; 80 } 81 byte_in_line() const82 std::size_t byte_in_line() const noexcept 83 { 84 return m_current.byte_in_line; 85 } 86 bump(const std::size_t in_count=1)87 void bump( const std::size_t in_count = 1 ) noexcept 88 { 89 internal::bump( m_current, in_count, Eol::ch ); 90 } 91 bump_in_this_line(const std::size_t in_count=1)92 void bump_in_this_line( const std::size_t in_count = 1 ) noexcept 93 { 94 internal::bump_in_this_line( m_current, in_count ); 95 } 96 bump_to_next_line(const std::size_t in_count=1)97 void bump_to_next_line( const std::size_t in_count = 1 ) noexcept 98 { 99 internal::bump_to_next_line( m_current, in_count ); 100 } 101 position(const iterator_t & it) const102 TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const 103 { 104 return TAO_PEGTL_NAMESPACE::position( it, m_source ); 105 } 106 107 protected: 108 iterator_t m_current; 109 const char* const m_end; 110 const Source m_source; 111 }; 112 113 template< typename Eol, typename Source > 114 class memory_input_base< tracking_mode::LAZY, Eol, Source > 115 { 116 public: 117 using iterator_t = const char*; 118 119 template< typename T > memory_input_base(const internal::iterator & in_begin,const char * in_end,T && in_source)120 memory_input_base( const internal::iterator& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 121 : m_begin( in_begin ), 122 m_current( in_begin.data ), 123 m_end( in_end ), 124 m_source( std::forward< T >( in_source ) ) 125 { 126 } 127 128 template< typename T > memory_input_base(const char * in_begin,const char * in_end,T && in_source)129 memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 130 : m_begin( in_begin ), 131 m_current( in_begin ), 132 m_end( in_end ), 133 m_source( std::forward< T >( in_source ) ) 134 { 135 } 136 137 memory_input_base( const memory_input_base& ) = delete; 138 memory_input_base( memory_input_base&& ) = delete; 139 140 ~memory_input_base() = default; 141 142 memory_input_base operator=( const memory_input_base& ) = delete; 143 memory_input_base operator=( memory_input_base&& ) = delete; 144 current() const145 const char* current() const noexcept 146 { 147 return m_current; 148 } 149 end(const std::size_t=0) const150 const char* end( const std::size_t /*unused*/ = 0 ) const noexcept 151 { 152 return m_end; 153 } 154 byte() const155 std::size_t byte() const noexcept 156 { 157 return std::size_t( current() - m_begin.data ); 158 } 159 bump(const std::size_t in_count=1)160 void bump( const std::size_t in_count = 1 ) noexcept 161 { 162 m_current += in_count; 163 } 164 bump_in_this_line(const std::size_t in_count=1)165 void bump_in_this_line( const std::size_t in_count = 1 ) noexcept 166 { 167 m_current += in_count; 168 } 169 bump_to_next_line(const std::size_t in_count=1)170 void bump_to_next_line( const std::size_t in_count = 1 ) noexcept 171 { 172 m_current += in_count; 173 } 174 position(const iterator_t it) const175 TAO_PEGTL_NAMESPACE::position position( const iterator_t it ) const 176 { 177 internal::iterator c( m_begin ); 178 internal::bump( c, std::size_t( it - m_begin.data ), Eol::ch ); 179 return TAO_PEGTL_NAMESPACE::position( c, m_source ); 180 } 181 182 protected: 183 const internal::iterator m_begin; 184 iterator_t m_current; 185 const char* const m_end; 186 const Source m_source; 187 }; 188 189 } // namespace internal 190 191 template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf, typename Source = std::string > 192 class memory_input 193 : public internal::memory_input_base< P, Eol, Source > 194 { 195 public: 196 static constexpr tracking_mode tracking_mode_v = P; 197 198 using eol_t = Eol; 199 using source_t = Source; 200 201 using typename internal::memory_input_base< P, Eol, Source >::iterator_t; 202 203 using action_t = internal::action_input< memory_input >; 204 205 using internal::memory_input_base< P, Eol, Source >::memory_input_base; 206 207 template< typename T > memory_input(const char * in_begin,const std::size_t in_size,T && in_source)208 memory_input( const char* in_begin, const std::size_t in_size, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 209 : memory_input( in_begin, in_begin + in_size, std::forward< T >( in_source ) ) 210 { 211 } 212 213 template< typename T > memory_input(const std::string & in_string,T && in_source)214 memory_input( const std::string& in_string, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 215 : memory_input( in_string.data(), in_string.size(), std::forward< T >( in_source ) ) 216 { 217 } 218 219 template< typename T > 220 memory_input( std::string&&, T&& ) = delete; 221 222 template< typename T > memory_input(const char * in_begin,T && in_source)223 memory_input( const char* in_begin, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 224 : memory_input( in_begin, std::strlen( in_begin ), std::forward< T >( in_source ) ) 225 { 226 } 227 228 template< typename T > memory_input(const char * in_begin,const char * in_end,T && in_source,const std::size_t in_byte,const std::size_t in_line,const std::size_t in_byte_in_line)229 memory_input( const char* in_begin, const char* in_end, T&& in_source, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_byte_in_line ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) 230 : memory_input( { in_begin, in_byte, in_line, in_byte_in_line }, in_end, std::forward< T >( in_source ) ) 231 { 232 } 233 234 memory_input( const memory_input& ) = delete; 235 memory_input( memory_input&& ) = delete; 236 237 ~memory_input() = default; 238 239 memory_input operator=( const memory_input& ) = delete; 240 memory_input operator=( memory_input&& ) = delete; 241 source() const242 const Source& source() const noexcept 243 { 244 return this->m_source; 245 } 246 empty() const247 bool empty() const noexcept 248 { 249 return this->current() == this->end(); 250 } 251 size(const std::size_t=0) const252 std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept 253 { 254 return std::size_t( this->end() - this->current() ); 255 } 256 peek_char(const std::size_t offset=0) const257 char peek_char( const std::size_t offset = 0 ) const noexcept 258 { 259 return this->current()[ offset ]; 260 } 261 peek_byte(const std::size_t offset=0) const262 unsigned char peek_byte( const std::size_t offset = 0 ) const noexcept 263 { 264 return static_cast< unsigned char >( peek_char( offset ) ); 265 } 266 iterator()267 iterator_t& iterator() noexcept 268 { 269 return this->m_current; 270 } 271 iterator() const272 const iterator_t& iterator() const noexcept 273 { 274 return this->m_current; 275 } 276 277 using internal::memory_input_base< P, Eol, Source >::position; 278 position() const279 TAO_PEGTL_NAMESPACE::position position() const 280 { 281 return position( iterator() ); 282 } 283 discard() const284 void discard() const noexcept 285 { 286 } 287 require(const std::size_t) const288 void require( const std::size_t /*unused*/ ) const noexcept 289 { 290 } 291 292 template< rewind_mode M > mark()293 internal::marker< iterator_t, M > mark() noexcept 294 { 295 return internal::marker< iterator_t, M >( iterator() ); 296 } 297 }; 298 299 } // namespace TAO_PEGTL_NAMESPACE 300 301 } // namespace tao 302 303 #endif 304