add tao cpp lib into project, small fixes

This commit is contained in:
Wieczorek Bartosz 2017-02-26 09:32:45 +01:00
parent c8ea15b17b
commit 9148ae53f9
180 changed files with 19931 additions and 90 deletions

View File

@ -11,5 +11,7 @@ find_package(Wt REQUIRED)
find_package(Sqlpp11 REQUIRED)
find_package(PostgreSQL REQUIRED)
include_directories(share/include)
add_subdirectory(share)
add_subdirectory(src)
add_subdirectory(tests)

View File

@ -0,0 +1 @@

44
share/include/tao/json.hh Normal file
View File

@ -0,0 +1,44 @@
// Copyright (c) 2015-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/json/
#ifndef TAOCPP_JSON_INCLUDE_JSON_HH
#define TAOCPP_JSON_INCLUDE_JSON_HH
// DOM value
#include "json/value.hh"
// SAX producers
//#include "json/sax/from_stream.hh" // includes PEGTL header/grammar
#include "json/sax/from_string.hh" // includes PEGTL header/grammar
#include "json/sax/parse_file.hh" // includes PEGTL header/grammar
#include "json/sax/from_value.hh" // DOM to SAX
// SAX consumers
#include "json/sax/to_stream.hh"
#include "json/sax/to_pretty_stream.hh"
#include "json/sax/to_string.hh"
#include "json/sax/to_value.hh" // SAX to DOM
// SAX other
#include "json/sax/hash.hh"
#include "json/sax/discard.hh"
#include "json/sax/tee.hh"
#include "json/sax/validate_event_order.hh"
#include "json/sax/debug.hh"
// DOM producers
#include "json/from_string.hh" // includes PEGTL header/grammar
#include "json/parse_file.hh" // includes PEGTL header/grammar
// DOM writers
#include "json/to_stream.hh"
#include "json/to_string.hh"
#include "json/stream.hh" // operator<<
// DOM support
#include "json/self_contained.hh"
#include "json/patch.hh"
//#include "json/diff.hh"
#include "json/schema.hh"
#endif

View File

@ -0,0 +1,11 @@
project(optional)
cmake_minimum_required(VERSION 2.8)
enable_testing()
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra")
add_executable(test_optional test_optional.cpp)
add_executable(test_type_traits test_type_traits.cpp)
add_test(test_optional test_optional)
add_test(test_type_traits test_type_traits)

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,39 @@
Optional
========
A single-header header-only library for representing optional (nullable) objects for C++14 (and C++11 to some extent) and passing them by value. This is the reference implementation of proposal N3793 (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html). Optional is now accepted into Library Fundamentals Technical Specification (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3848.html). The interface is based on Fernando Cacciola's Boost.Optional library (see http://www.boost.org/doc/libs/1_52_0/libs/optional/doc/html/index.html)
Usage
-----
```cpp
optional<int> readInt(); // this function may return int or a not-an-int
if (optional<int> oi = readInt()) // did I get a real int
cout << "my int is: " << *oi; // use my int
else
cout << "I have no int";
```
For more usage examples and the overview see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html
Supported compilers
-------------------
Clang 3.2, Clang 3.4, G++ 4.7.2, G++ 4.8.1. Tested only with libstdc++, versions 20130531, 20120920, 20110428. Others have reported it also works with libc++.
Known Issues
------------
- Currently, the reference (and the only known) impementation of certain pieces of functionality explore what C++11 identifies as undefined behavior (see national body comment FI 15: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3770.html#FI15). This is mostly why Optional was removed from C++14 and put into Library Fundamentals TS. Luckily what the Standard identifies as UB is well defined on all known platforms. We expect that the C++14 wil fix this problem, so that our trick becomes well-defined.
- In libstdc++ versions below 20130531 the constructor taking `initializer_list` argument is not `constexpr`. This is because `initializer_list` operations are not `constexpr` in C++11. This works however in version 20130531. It is also not enabled for libc++ because I do not have access to it and do nto know if it provides `constexpr` `initializer_list`.
- In G++ 4.7.2 and 4.8.0 member function `value_or` does not have rvalue reference overload. These compilers do not support rvalue overloding on `*this`.
- In order for the library to work with slightly older compilers, we emulate some missing type traits. On some platforms we cannot correctly detect the available features, and attempts at workarounds for missing type trait definitions can cause compile-time errors. Define macro `TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS` if you know that all the necessary type traits are defined, and no emulation is required.
License
-------
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).

View File

@ -0,0 +1,10 @@
Copyright (C) 2011-2012 Andrzej Krzemienski
Distributed under the Boost Software License, Version 1.0
(see accompanying file LICENSE_1_0.txt or a copy at
http://www.boost.org/LICENSE_1_0.txt)
The idea and interface is based on Boost.Optional library
authored by Fernando Luis Cacciola Carballal
Home at https://github.com/akrzemi1/Optional

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#if (defined __clang__)
namespace std { class type_info; }
#endif
# include "optional.hpp"
namespace std { namespace experimental {
struct Val
{
Val(){}
Val( Val const & ){}
Val( Val && ) noexcept {}
Val & operator=( Val const & ) = delete;
Val & operator=( Val && ) noexcept = delete;
};
struct Safe
{
Safe(){}
Safe( Safe const & ){}
Safe( Safe && ) noexcept {}
Safe & operator=( Safe const & ){ return *this; }
Safe & operator=( Safe && ) noexcept { return *this; }
};
struct Unsafe
{
Unsafe(){}
Unsafe( Unsafe const & ){}
Unsafe( Unsafe && ){}
Unsafe & operator=( Unsafe const & ){ return *this; }
Unsafe & operator=( Unsafe && ) { return *this; }
};
struct VoidNothrowBoth
{
VoidNothrowBoth(VoidNothrowBoth&&) noexcept(true) {};
void operator=(VoidNothrowBoth&&) noexcept(true) {}; // note void return type
};
static_assert(is_nothrow_move_constructible<Safe>::value, "WTF!");
static_assert(!is_nothrow_move_constructible<Unsafe>::value, "WTF!");
static_assert(is_assignable<Safe&, Safe&&>::value, "WTF!");
static_assert(!is_assignable<Val&, Val&&>::value, "WTF!");
static_assert(is_nothrow_move_assignable<Safe>::value, "WTF!");
static_assert(!is_nothrow_move_assignable<Unsafe>::value, "WTF!");
static_assert(is_nothrow_move_constructible<VoidNothrowBoth>::value, "WTF!");
static_assert(is_nothrow_move_assignable<VoidNothrowBoth>::value, "WTF!");
}} // namespace std::experimental
int main() { }

2137
share/include/tao/json/external/double.hh vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,658 @@
// The Art of C++ / Operators
// Copyright (c) 2013-2016 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/operators/
#ifndef TAOCPP_OPERATORS_INCLUDE_OPERATORS_HPP
#define TAOCPP_OPERATORS_INCLUDE_OPERATORS_HPP
#include <utility>
#ifndef TAOCPP_NO_RVALUE_REFERENCE_RESULTS
#define TAOCPP_OPERATORS_BASIC_OP( name, op ) \
template< typename T, typename U = T > \
class name \
{ \
friend T operator op( const T& lhs, const U& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const T& lhs, U&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T&& operator op( T&& lhs, const U& rhs ) \
noexcept( noexcept( lhs op##= rhs ) ) \
{ \
lhs op##= rhs; \
return std::move( lhs ); \
} \
\
friend T&& operator op( T&& lhs, U&& rhs ) \
noexcept( noexcept( lhs op##= std::move( rhs ) ) ) \
{ \
lhs op##= std::move( rhs ); \
return std::move( lhs ); \
} \
}
#else
#define TAOCPP_OPERATORS_BASIC_OP( name, op ) \
template< typename T, typename U = T > \
class name \
{ \
friend T operator op( const T& lhs, const U& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const T& lhs, U&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T operator op( T&& lhs, const U& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( T&& lhs, U&& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
}
#endif
#define TAOCPP_OPERATORS_BASIC_OP_LEFT( name, op ) \
template< typename T, typename U > \
class name##_left \
{ \
friend T operator op( const U& lhs, const T& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const U& lhs, T&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T operator op( U&& lhs, const T& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( U&& lhs, T&& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
}
#ifndef TAOCPP_NO_RVALUE_REFERENCE_RESULTS
#define TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( name, op ) \
template< typename T, typename U = T > \
class commutative_##name \
{ \
friend T operator op( const T& lhs, const U& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const T& lhs, U&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T&& operator op( T&& lhs, const U& rhs ) \
noexcept( noexcept( lhs op##= rhs ) ) \
{ \
lhs op##= rhs; \
return std::move( lhs ); \
} \
\
friend T&& operator op( T&& lhs, U&& rhs ) \
noexcept( noexcept( lhs op##= std::move( rhs ) ) ) \
{ \
lhs op##= std::move( rhs ); \
return std::move( lhs ); \
} \
\
friend T operator op( const U& lhs, const T& rhs ) \
noexcept( noexcept( T( rhs ), std::declval< T& >() op##= lhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( rhs ); \
nrv op##= lhs; \
return nrv; \
} \
\
friend T&& operator op( const U& lhs, T&& rhs ) \
noexcept( noexcept( rhs op##= lhs ) ) \
{ \
rhs op##= lhs; \
return std::move( rhs ); \
} \
\
friend T operator op( U&& lhs, const T& rhs ) \
noexcept( noexcept( T( rhs ), std::declval< T& >() op##= std::move( lhs ) ) ) \
{ \
T nrv( rhs ); \
nrv op##= std::move( lhs ); \
return nrv; \
} \
\
friend T&& operator op( U&& lhs, T&& rhs ) \
noexcept( noexcept( rhs op##= std::move( lhs ) ) ) \
{ \
rhs op##= std::move( lhs ); \
return std::move( rhs ); \
} \
}; \
\
template< typename T > \
class commutative_##name< T > \
{ \
friend T operator op( const T& lhs, const T& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T&& operator op( const T& lhs, T&& rhs ) \
noexcept( noexcept( rhs op##= lhs ) ) \
{ \
rhs op##= lhs; \
return std::move( rhs ); \
} \
\
friend T&& operator op( T&& lhs, const T& rhs ) \
noexcept( noexcept( lhs op##= rhs ) ) \
{ \
lhs op##= rhs; \
return std::move( lhs ); \
} \
\
friend T&& operator op( T&& lhs, T&& rhs ) \
noexcept( noexcept( lhs op##= std::move( rhs ) ) ) \
{ \
lhs op##= std::move( rhs ); \
return std::move( lhs ); \
} \
}
#else
#define TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( name, op ) \
template< typename T, typename U = T > \
class commutative_##name \
{ \
friend T operator op( const T& lhs, const U& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const T& lhs, U&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T operator op( T&& lhs, const U& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( T&& lhs, U&& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T operator op( const U& lhs, const T& rhs ) \
noexcept( noexcept( T( rhs ), std::declval< T& >() op##= lhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( rhs ); \
nrv op##= lhs; \
return nrv; \
} \
\
friend T operator op( const U& lhs, T&& rhs ) \
noexcept( noexcept( T( std::move( rhs ) ), std::declval< T& >() op##= lhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( rhs ) ); \
nrv op##= lhs; \
return nrv; \
} \
\
friend T operator op( U&& lhs, const T& rhs ) \
noexcept( noexcept( T( rhs ), std::declval< T& >() op##= std::move( lhs ) ) ) \
{ \
T nrv( rhs ); \
nrv op##= std::move( lhs ); \
return nrv; \
} \
\
friend T operator op( U&& lhs, T&& rhs ) \
noexcept( noexcept( T( std::move( rhs ) ), std::declval< T& >() op##= std::move( lhs ) ) ) \
{ \
T nrv( std::move( rhs ) ); \
nrv op##= std::move( lhs ); \
return nrv; \
} \
}; \
\
template< typename T > \
class commutative_##name< T > \
{ \
friend T operator op( const T& lhs, const T& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( const T& lhs, T&& rhs ) \
noexcept( noexcept( T( lhs ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( lhs ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
\
friend T operator op( T&& lhs, const T& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= rhs, T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= rhs; \
return nrv; \
} \
\
friend T operator op( T&& lhs, T&& rhs ) \
noexcept( noexcept( T( std::move( lhs ) ), std::declval< T& >() op##= std::move( rhs ), T( std::declval< T& >() ) ) ) \
{ \
T nrv( std::move( lhs ) ); \
nrv op##= std::move( rhs ); \
return nrv; \
} \
}
#endif
namespace tao
{
namespace operators
{
template< typename T, typename U = T >
class equality_comparable
{
friend bool operator!=( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs == rhs ) ) )
{
return !static_cast< bool >( lhs == rhs );
}
friend bool operator==( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs == lhs ) ) )
{
return static_cast< bool >( rhs == lhs );
}
friend bool operator!=( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs != lhs ) ) )
{
return static_cast< bool >( rhs != lhs );
}
};
template< typename T >
class equality_comparable< T >
{
friend bool operator!=( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( lhs == rhs ) ) )
{
return !static_cast< bool >( lhs == rhs );
}
};
template< typename T, typename U = T >
class less_than_comparable
{
friend bool operator<=( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs > rhs ) ) )
{
return !static_cast< bool >( lhs > rhs );
}
friend bool operator>=( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ) ) )
{
return !static_cast< bool >( lhs < rhs );
}
friend bool operator<( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs > lhs ) ) )
{
return static_cast< bool >( rhs > lhs );
}
friend bool operator>( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ) ) )
{
return static_cast< bool >( rhs < lhs );
}
friend bool operator<=( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs >= lhs ) ) )
{
return static_cast< bool >( rhs >= lhs );
}
friend bool operator>=( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs <= lhs ) ) )
{
return static_cast< bool >( rhs <= lhs );
}
};
template< typename T >
class less_than_comparable< T >
{
friend bool operator>( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ) ) )
{
return static_cast< bool >( rhs < lhs );
}
friend bool operator<=( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ) ) )
{
return !static_cast< bool >( rhs < lhs );
}
friend bool operator>=( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ) ) )
{
return !static_cast< bool >( lhs < rhs );
}
};
template< typename T, typename U = T >
class totally_ordered
: less_than_comparable< T, U >, equality_comparable< T, U >
{
};
template< typename T, typename U = T >
class equivalent
{
friend bool operator==( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ), static_cast< bool >( lhs > rhs ) ) )
{
return !static_cast< bool >( lhs < rhs ) && !static_cast< bool >( lhs > rhs );
}
};
template< typename T >
class equivalent< T >
{
friend bool operator==( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ) ) )
{
return !static_cast< bool >( lhs < rhs ) && !static_cast< bool >( rhs < lhs );
}
};
template< typename T, typename U = T >
class partially_ordered
{
friend bool operator<=( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ), static_cast< bool >( lhs == rhs ) ) )
{
return static_cast< bool >( lhs < rhs ) || static_cast< bool >( lhs == rhs );
}
friend bool operator>=( const T& lhs, const U& rhs )
noexcept( noexcept( static_cast< bool >( lhs > rhs ), static_cast< bool >( lhs == rhs ) ) )
{
return static_cast< bool >( lhs > rhs ) || static_cast< bool >( lhs == rhs );
}
friend bool operator<( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs > lhs ) ) )
{
return static_cast< bool >( rhs > lhs );
}
friend bool operator>( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ) ) )
{
return static_cast< bool >( rhs < lhs );
}
friend bool operator<=( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs >= lhs ) ) )
{
return static_cast< bool >( rhs >= lhs );
}
friend bool operator>=( const U& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs <= lhs ) ) )
{
return static_cast< bool >( rhs <= lhs );
}
};
template< typename T >
class partially_ordered< T >
{
friend bool operator>( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ) ) )
{
return static_cast< bool >( rhs < lhs );
}
friend bool operator<=( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( lhs < rhs ), static_cast< bool >( lhs == rhs ) ) )
{
return static_cast< bool >( lhs < rhs ) || static_cast< bool >( lhs == rhs );
}
friend bool operator>=( const T& lhs, const T& rhs )
noexcept( noexcept( static_cast< bool >( rhs < lhs ), static_cast< bool >( lhs == rhs ) ) )
{
return static_cast< bool >( rhs < lhs ) || static_cast< bool >( lhs == rhs );
}
};
TAOCPP_OPERATORS_BASIC_OP( addable, + );
TAOCPP_OPERATORS_BASIC_OP_LEFT( addable, + );
TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( addable, + );
TAOCPP_OPERATORS_BASIC_OP( subtractable, - );
TAOCPP_OPERATORS_BASIC_OP_LEFT( subtractable, - );
TAOCPP_OPERATORS_BASIC_OP( multipliable, * );
TAOCPP_OPERATORS_BASIC_OP_LEFT( multipliable, * );
TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( multipliable, * );
TAOCPP_OPERATORS_BASIC_OP( dividable, / );
TAOCPP_OPERATORS_BASIC_OP_LEFT( dividable, / );
TAOCPP_OPERATORS_BASIC_OP( modable, % );
TAOCPP_OPERATORS_BASIC_OP_LEFT( modable, % );
template< typename T, typename U = T >
class ring
: commutative_addable< T, U >, subtractable< T, U >, subtractable_left< T, U >, multipliable< T, U >
{
};
template< typename T >
class ring< T >
: commutative_addable< T >, subtractable< T >, multipliable< T >
{
};
template< typename T, typename U = T >
class ordered_ring
: ring< T, U >, totally_ordered< T, U >
{
};
template< typename T, typename U = T >
class commutative_ring
: commutative_addable< T, U >, subtractable< T, U >, subtractable_left< T, U >, commutative_multipliable< T, U >
{
};
template< typename T >
class commutative_ring< T >
: commutative_addable< T >, subtractable< T >, commutative_multipliable< T >
{
};
template< typename T, typename U = T >
class ordered_commutative_ring
: commutative_ring< T, U >, totally_ordered< T, U >
{
};
template< typename T, typename U = T >
class field
: commutative_ring< T, U >, dividable< T, U >, dividable_left< T, U >
{
};
template< typename T >
class field< T >
: commutative_ring< T >, dividable< T >
{
};
template< typename T, typename U = T >
class ordered_field
: field< T, U >, totally_ordered< T, U >
{
};
TAOCPP_OPERATORS_BASIC_OP( andable, & );
TAOCPP_OPERATORS_BASIC_OP_LEFT( andable, & );
TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( andable, & );
TAOCPP_OPERATORS_BASIC_OP( orable, | );
TAOCPP_OPERATORS_BASIC_OP_LEFT( orable, | );
TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( orable, | );
TAOCPP_OPERATORS_BASIC_OP( xorable, ^ );
TAOCPP_OPERATORS_BASIC_OP_LEFT( xorable, ^ );
TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE( xorable, ^ );
template< typename T, typename U = T >
class bitwise
: andable< T, U >, orable< T, U >, xorable< T, U >
{
};
template< typename T, typename U >
class bitwise_left
: andable_left< T, U >, orable_left< T, U >, xorable_left< T, U >
{
};
template< typename T, typename U = T >
class commutative_bitwise
: commutative_andable< T, U >, commutative_orable< T, U >, commutative_xorable< T, U >
{
};
TAOCPP_OPERATORS_BASIC_OP( left_shiftable, << );
TAOCPP_OPERATORS_BASIC_OP( right_shiftable, >> );
template< typename T, typename U = T >
class shiftable
: left_shiftable< T, U >, right_shiftable< T, U >
{
};
template< typename T >
class incrementable
{
friend T operator++( T& arg, int )
noexcept( noexcept( T( arg ), ++arg, T( std::declval< T >() ) ) )
{
const T nrv( arg );
++arg;
return nrv;
}
};
template< typename T >
class decrementable
{
friend T operator--( T& arg, int )
noexcept( noexcept( T( arg ), --arg, T( std::declval< T >() ) ) )
{
const T nrv( arg );
--arg;
return nrv;
}
};
template< typename T >
class unit_steppable
: incrementable< T >, decrementable< T >
{
};
}
}
#undef TAOCPP_OPERATORS_BASIC_OP
#undef TAOCPP_OPERATORS_BASIC_OP_LEFT
#undef TAOCPP_OPERATORS_BASIC_OP_COMMUTATIVE
#endif

View File

@ -0,0 +1,33 @@
// The Art of C++
// Copyright (c) 2016 Daniel Frey
#ifndef TAOCPP_INCLUDE_OPTIONAL_HPP
#define TAOCPP_INCLUDE_OPTIONAL_HPP
#ifndef TAOCPP_USE_STD_OPTIONAL
#if __cplusplus >= 201799L // TODO: Fix when C++17 is published with support for std::optional
#include <optional>
#define TAOCPP_USE_STD_OPTIONAL
#elif ( __cplusplus >= 201402L ) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
#include <experimental/optional>
#else
#include "akrzemi1/optional.hpp"
#endif
#endif
namespace tao
{
#if TAOCPP_USE_STD_OPTIONAL
using std::optional;
using std::nullopt;
using std::in_place;
using std::make_optional;
#else
using std::experimental::optional;
using std::experimental::nullopt;
using std::experimental::in_place;
using std::experimental::make_optional;
#endif
}
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_HH
#define TAO_CPP_PEGTL_HH
#include "pegtl/parse.hh"
#include "pegtl/rules.hh"
#include "pegtl/ascii.hh"
#include "pegtl/utf8.hh"
#include "pegtl/utf16.hh"
#include "pegtl/utf32.hh"
// The following files can be included whenever needed; they
// are not included by default because they include <iostream>.
// #include "pegtl/trace.hh"
// #include "pegtl/analyze.hh"
#include "pegtl/string_parser.hh"
#include "pegtl/file_parser.hh"
#endif

View File

@ -0,0 +1,116 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ACTION_INPUT_HH
#define TAO_CPP_PEGTL_ACTION_INPUT_HH
#include <string>
#include <cstddef>
#include "eol.hh"
#include "position_info.hh"
#include "internal/input_data.hh"
#include "internal/input_mark.hh"
namespace tao_json_pegtl
{
template< typename Eol >
class basic_memory_input;
template< typename Eol >
class basic_action_input
{
public:
using eol_t = Eol;
using mark_t = internal::input_mark;
using data_t = internal::input_data;
using action_t = basic_action_input< Eol >;
using memory_t = basic_memory_input< Eol >;
using position_t = position_info;
using exception_t = basic_parse_error< position_info >;
basic_action_input( const internal::input_mark & m, const internal::input_data & d )
: m_data( m.byte(), m.line(), m.byte_in_line(), m.begin(), d.begin, d.source )
{ }
basic_action_input( const std::size_t in_byte, const std::size_t in_line, const std::size_t in_byte_in_line, const char * in_begin, const char * in_end, const char * in_source )
: m_data( in_byte, in_line, in_byte_in_line, in_begin, in_end, in_source )
{ }
bool empty() const
{
return m_data.begin == m_data.end;
}
std::size_t size( const std::size_t = 0 ) const
{
return m_data.end - m_data.begin;
}
const char * begin() const
{
return m_data.begin;
}
const char * end( const std::size_t = 0 ) const
{
return m_data.end;
}
std::size_t byte() const
{
return m_data.byte;
}
std::size_t line() const
{
return m_data.line;
}
std::size_t byte_in_line() const
{
return m_data.byte_in_line;
}
const char * source() const
{
return m_data.source;
}
std::string string() const
{
return std::string( m_data.begin, m_data.end );
}
char peek_char( const std::size_t offset = 0 ) const
{
return m_data.begin[ offset ];
}
unsigned char peek_byte( const std::size_t offset = 0 ) const
{
return static_cast< unsigned char >( peek_char( offset ) );
}
const internal::input_data & data() const
{
return m_data;
}
position_t position() const
{
return position_info( m_data );
}
private:
internal::input_data m_data;
};
using action_input = basic_action_input< lf_crlf_eol >;
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,129 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_ANALYZE_CYCLES_HH
#define TAO_CPP_PEGTL_ANALYSIS_ANALYZE_CYCLES_HH
#include <cassert>
#include <map>
#include <set>
#include <utility>
#include <iostream>
#include "grammar_info.hh"
#include "insert_guard.hh"
namespace tao_json_pegtl
{
namespace analysis
{
class analyze_cycles_impl
{
protected:
explicit
analyze_cycles_impl( const bool verbose )
: m_verbose( verbose ),
m_problems( 0 )
{ }
const bool m_verbose;
unsigned m_problems;
grammar_info m_info;
std::set< std::string > m_stack;
std::map< std::string, bool > m_cache;
std::map< std::string, bool > m_results;
const std::map< std::string, rule_info >::const_iterator find( const std::string & name ) const
{
const auto iter = m_info.map.find( name );
assert( iter != m_info.map.end() );
return iter;
}
bool work( const std::map< std::string, rule_info >::const_iterator & start, const bool accum )
{
const auto j = m_cache.find( start->first );
if ( j != m_cache.end() ) {
return j->second;
}
if ( const auto g = make_insert_guard( m_stack, start->first ) ) {
switch ( start->second.type ) {
case rule_type::ANY: {
bool a = false;
for ( const auto & r : start->second.rules ) {
a = a || work( find( r ), accum || a );
}
return m_cache[ start->first ] = true;
}
case rule_type::OPT: {
bool a = false;
for ( const auto & r : start->second.rules ) {
a = a || work( find( r ), accum || a );
}
return m_cache[ start->first ] = false;
}
case rule_type::SEQ: {
bool a = false;
for ( const auto & r : start->second.rules ) {
a = a || work( find( r ), accum || a );
}
return m_cache[ start->first ] = a;
}
case rule_type::SOR: {
bool a = true;
for ( const auto & r : start->second.rules ) {
a = a && work( find( r ), accum );
}
return m_cache[ start->first ] = a;
}
}
throw std::runtime_error( "code should be unreachable" ); // LCOV_EXCL_LINE
}
if ( ! accum ) {
++m_problems;
if ( m_verbose ) {
std::cout << "problem: cycle without progress detected at rule class " << start->first << std::endl;
}
}
return m_cache[ start->first ] = accum;
}
};
template< typename Grammar >
class analyze_cycles
: private analyze_cycles_impl
{
public:
explicit
analyze_cycles( const bool verbose )
: analyze_cycles_impl( verbose )
{
Grammar::analyze_t::template insert< Grammar >( m_info );
}
std::size_t problems()
{
for ( auto i = m_info.map.begin(); i != m_info.map.end(); ++i ) {
m_results[ i->first ] = work( i, false );
m_cache.clear();
}
return m_problems;
}
template< typename Rule >
bool consumes() const
{
const auto i = m_results.find( internal::demangle< Rule >() );
assert( i != m_results.end() );
return i->second;
}
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_COUNTED_HH
#define TAO_CPP_PEGTL_ANALYSIS_COUNTED_HH
#include "generic.hh"
namespace tao_json_pegtl
{
namespace analysis
{
template< rule_type Type, unsigned Count, typename ... Rules >
struct counted
: generic< ( Count != 0 ) ? Type : rule_type::OPT, Rules ... >
{ };
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,33 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_GENERIC_HH
#define TAO_CPP_PEGTL_ANALYSIS_GENERIC_HH
#include "rule_type.hh"
#include "insert_rules.hh"
#include "grammar_info.hh"
namespace tao_json_pegtl
{
namespace analysis
{
template< rule_type Type, typename ... Rules >
struct generic
{
template< typename Name >
static std::string insert( grammar_info & g )
{
const auto r = g.insert< Name >( Type );
if ( r.second ) {
insert_rules< Rules ... >::insert( g, r.first->second );
}
return r.first->first;
}
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,35 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_GRAMMAR_INFO_HH
#define TAO_CPP_PEGTL_ANALYSIS_GRAMMAR_INFO_HH
#include <map>
#include <string>
#include <utility>
#include "../internal/demangle.hh"
#include "rule_info.hh"
namespace tao_json_pegtl
{
namespace analysis
{
struct grammar_info
{
using map_t = std::map< std::string, rule_info >;
map_t map;
template< typename Name >
std::pair< map_t::iterator, bool > insert( const rule_type type )
{
return map.insert( map_t::value_type( internal::demangle< Name >(), rule_info( type ) ) );
}
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,59 @@
// Copyright (c) 2014-2017 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_INSERT_GUARD_HH
#define TAO_CPP_PEGTL_ANALYSIS_INSERT_GUARD_HH
#include <utility>
namespace tao_json_pegtl
{
namespace analysis
{
template< typename C >
class insert_guard
{
public:
insert_guard( insert_guard && g ) noexcept
: m_i( g.m_i ),
m_c( g.m_c )
{
g.m_c = 0;
}
insert_guard( C & cs, const typename C::value_type & ts )
: m_i( cs.insert( ts ) ),
m_c( & cs )
{ }
~insert_guard()
{
if ( m_c && m_i.second ) {
m_c->erase( m_i.first );
}
}
insert_guard( const insert_guard & ) = delete;
void operator= ( const insert_guard & ) = delete;
explicit operator bool () const
{
return m_i.second;
}
private:
const std::pair< typename C::iterator, bool > m_i;
C * m_c;
};
template< typename C, typename T >
insert_guard< C > make_insert_guard( C & c, const T & t )
{
return insert_guard< C >( c, t );
}
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_INSERT_RULES_HH
#define TAO_CPP_PEGTL_ANALYSIS_INSERT_RULES_HH
#include "rule_info.hh"
#include "grammar_info.hh"
namespace tao_json_pegtl
{
namespace analysis
{
template< typename ... > struct insert_rules;
template<>
struct insert_rules<>
{
static void insert( grammar_info &, rule_info & )
{ }
};
template< typename Rule, typename ... Rules >
struct insert_rules< Rule, Rules ... >
{
static void insert( grammar_info & g, rule_info & r )
{
r.rules.push_back( Rule::analyze_t::template insert< Rule >( g ) );
insert_rules< Rules ... >::insert( g, r );
}
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,31 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_RULE_INFO_HH
#define TAO_CPP_PEGTL_ANALYSIS_RULE_INFO_HH
#include <string>
#include <vector>
#include "rule_type.hh"
namespace tao_json_pegtl
{
namespace analysis
{
struct rule_info
{
explicit
rule_info( const rule_type in_type )
: type( in_type )
{ }
rule_type type;
std::vector< std::string > rules;
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,23 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYSIS_RULE_TYPE_HH
#define TAO_CPP_PEGTL_ANALYSIS_RULE_TYPE_HH
namespace tao_json_pegtl
{
namespace analysis
{
enum class rule_type : char
{
ANY, // Consumption-on-success is always true; assumes bounded repetition of conjunction of sub-rules.
OPT, // Consumption-on-success not necessarily true; assumes bounded repetition of conjunction of sub-rules.
SEQ, // Consumption-on-success depends on consumption of (non-zero bounded repetition of) conjunction of sub-rules.
SOR // Consumption-on-success depends on consumption of (non-zero bounded repetition of) disjunction of sub-rules.
};
} // namespace analysis
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,19 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ANALYZE_HH
#define TAO_CPP_PEGTL_ANALYZE_HH
#include "analysis/analyze_cycles.hh"
namespace tao_json_pegtl
{
template< typename Rule >
std::size_t analyze( const bool verbose = true )
{
return analysis::analyze_cycles< Rule >( verbose ).problems();
}
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,17 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_APPLY_MODE_HH
#define TAO_CPP_PEGTL_APPLY_MODE_HH
namespace tao_json_pegtl
{
enum class apply_mode : bool
{
ACTION = true,
NOTHING = false
};
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,47 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_ASCII_HH
#define TAO_CPP_PEGTL_ASCII_HH
#include "internal/rules.hh"
#include "internal/result_on_found.hh"
namespace tao_json_pegtl
{
inline namespace ascii
{
struct alnum : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9' > {};
struct alpha : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {};
struct any : internal::any< internal::peek_char > {};
struct blank : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ', '\t' > {};
struct digit : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, '0', '9' > {};
struct eol : internal::eol {};
struct eolf : internal::eolf {};
struct identifier_first : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '_' > {};
struct identifier_other : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9', '_' > {};
struct identifier : internal::seq< identifier_first, internal::star< identifier_other > > {};
template< char ... Cs > struct istring : internal::istring< Cs ... > {};
struct lower : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, 'a', 'z' > {};
template< char ... Cs > struct not_one : internal::one< internal::result_on_found::FAILURE, internal::peek_char, Cs ... > {};
template< char Lo, char Hi > struct not_range : internal::range< internal::result_on_found::FAILURE, internal::peek_char, Lo, Hi > {};
struct nul : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, char( 0 ) > {};
template< char ... Cs > struct one : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, Cs ... > {};
struct print : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, char( 32 ), char( 126 ) > {};
template< char Lo, char Hi > struct range : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, Lo, Hi > {};
template< char ... Cs > struct ranges : internal::ranges< internal::peek_char, Cs ... > {};
struct seven : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, char( 0 ), char( 127 ) > {};
struct shebang : internal::if_must< internal::string< '#', '!' >, internal::until< internal::eolf > > {};
struct space : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ', '\n', '\r', '\t', '\v', '\f' > {};
template< char ... Cs > struct string : internal::string< Cs ... > {};
template< char C > struct two : internal::string< C, C > {};
struct upper : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, 'A', 'Z' > {};
struct xdigit : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {};
} // namespace ascii
} // namespace tao_json_pegtl
#include "internal/pegtl_string.hh"
#endif

View File

@ -0,0 +1,171 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_BUFFER_INPUT_HH
#define TAO_CPP_PEGTL_BUFFER_INPUT_HH
#include <memory>
#include <cstring>
#include <cstddef>
#include "eol.hh"
#include "position_info.hh"
#include "internal/input_data.hh"
#include "internal/input_mark.hh"
namespace tao_json_pegtl
{
template< typename Eol >
class basic_action_input;
template< typename Eol >
class basic_memory_input;
template< typename Eol, typename Reader >
class basic_buffer_input
{
public:
using eol_t = Eol;
using reader_t = Reader;
using mark_t = internal::input_mark;
using data_t = internal::input_data;
using action_t = basic_action_input< Eol >;
using memory_t = basic_memory_input< Eol >;
using position_t = position_info;
using exception_t = basic_parse_error< position_info >;
template< typename ... As >
basic_buffer_input( const char * in_source, const std::size_t maximum, As && ... as )
: m_reader( std::forward< As >( as ) ... ),
m_maximum( maximum ),
m_buffer( new char[ maximum ] ),
m_data( 0, 1, 0, m_buffer.get(), m_buffer.get(), in_source )
{ }
basic_buffer_input( const basic_buffer_input & ) = delete;
void operator= ( const basic_buffer_input & ) = delete;
bool empty()
{
require( 1 );
return m_data.begin == m_data.end;
}
std::size_t size( const std::size_t amount )
{
require( amount );
return m_data.end - m_data.begin;
}
const char * begin() const
{
return m_data.begin;
}
const char * end( const std::size_t amount )
{
require( amount );
return m_data.end;
}
std::size_t byte() const
{
return m_data.byte;
}
std::size_t line() const
{
return m_data.line;
}
std::size_t byte_in_line() const
{
return m_data.byte_in_line;
}
const char * source() const
{
return m_data.source;
}
char peek_char( const std::size_t offset = 0 ) const
{
return m_data.begin[ offset ];
}
unsigned char peek_byte( const std::size_t offset = 0 ) const
{
return static_cast< unsigned char >( peek_char( offset ) );
}
void bump( const std::size_t count = 1 )
{
m_data.bump( count, Eol::ch );
}
void bump_in_this_line( const std::size_t count = 1 )
{
m_data.bump_in_this_line( count );
}
void bump_to_next_line( const std::size_t count = 1 )
{
m_data.bump_to_next_line( count );
}
void discard()
{
const auto s = m_data.end - m_data.begin;
std::memmove( m_buffer.get(), m_data.begin, s );
m_data.begin = m_buffer.get();
m_data.end = m_buffer.get() + s;
}
void require( const std::size_t amount )
{
if ( m_data.begin + amount > m_data.end ) {
if ( m_data.begin + amount <= m_buffer.get() + m_maximum ) {
if ( const auto r = m_reader( const_cast< char * >( m_data.end ), amount - std::size_t( m_data.end - m_data.begin ) ) ) {
m_data.end += r;
}
else {
m_maximum = 0;
}
}
}
}
internal::input_mark mark()
{
return internal::input_mark( m_data );
}
const internal::input_data & data() const
{
return m_data;
}
position_t position() const
{
return position_info( m_data );
}
private:
Reader m_reader;
std::size_t m_maximum;
std::unique_ptr< char[] > m_buffer;
internal::input_data m_data;
};
template< typename Reader >
using buffer_input = basic_buffer_input< lf_crlf_eol, Reader >;
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_ABNF_HH
#define TAO_CPP_PEGTL_CONTRIB_ABNF_HH
#include "../internal/rules.hh"
namespace tao_json_pegtl
{
namespace abnf
{
// Core ABNF rules according to RFC 5234, Appendix B
struct ALPHA : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {};
struct BIT : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, '0', '1' > {};
struct CHAR : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, char( 1 ), char( 127 ) > {};
struct CR : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, '\r' > {};
struct CRLF : internal::string< '\r', '\n' > {};
struct CTL : internal::ranges< internal::peek_char, char( 0 ), char( 31 ), char( 127 ) > {};
struct DIGIT : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, '0', '9' > {};
struct DQUOTE : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, '"' > {};
struct HEXDIG : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {};
struct HTAB : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, '\t' > {};
struct LF : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, '\n' > {};
struct LWSP : internal::star< internal::sor< internal::string< '\r', '\n' >, internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ', '\t' > >, internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ', '\t' > > {};
struct OCTET : internal::any< internal::peek_char > {};
struct SP : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ' > {};
struct VCHAR : internal::range< internal::result_on_found::SUCCESS, internal::peek_char, char( 33 ), char( 126 ) > {};
struct WSP : internal::one< internal::result_on_found::SUCCESS, internal::peek_char, ' ', '\t' > {};
} // namespace abnf
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,69 @@
// Copyright (c) 2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_ALPHABET_HH
#define TAO_CPP_PEGTL_CONTRIB_ALPHABET_HH
namespace tao_json_pegtl
{
inline namespace alphabet
{
static const int a = 'a';
static const int b = 'b';
static const int c = 'c';
static const int d = 'd';
static const int e = 'e';
static const int f = 'f';
static const int g = 'g';
static const int h = 'h';
static const int i = 'i';
static const int j = 'j';
static const int k = 'k';
static const int l = 'l';
static const int m = 'm';
static const int n = 'n';
static const int o = 'o';
static const int p = 'p';
static const int q = 'q';
static const int r = 'r';
static const int s = 's';
static const int t = 't';
static const int u = 'u';
static const int v = 'v';
static const int w = 'w';
static const int x = 'x';
static const int y = 'y';
static const int z = 'z';
static const int A = 'A';
static const int B = 'B';
static const int C = 'C';
static const int D = 'D';
static const int E = 'E';
static const int F = 'F';
static const int G = 'G';
static const int H = 'H';
static const int I = 'I';
static const int J = 'J';
static const int K = 'K';
static const int L = 'L';
static const int M = 'M';
static const int N = 'N';
static const int O = 'O';
static const int P = 'P';
static const int Q = 'Q';
static const int R = 'R';
static const int S = 'S';
static const int T = 'T';
static const int U = 'U';
static const int V = 'V';
static const int W = 'W';
static const int X = 'X';
static const int Y = 'Y';
static const int Z = 'Z';
} // namespace alphabet
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,68 @@
// Copyright (c) 2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_CHANGES_HH
#define TAO_CPP_PEGTL_CONTRIB_CHANGES_HH
#include <type_traits>
#include "../normal.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct dummy_disabled_state
{
template< typename ... Ts >
void success( Ts && ... )
{ }
};
template< tao_json_pegtl::apply_mode A, typename State >
using state_disable_helper = typename std::conditional< A == tao_json_pegtl::apply_mode::ACTION, State, dummy_disabled_state >::type;
} // namespace internal
template< typename Rule, typename State, template< typename ... > class Base = tao_json_pegtl::normal >
struct change_state
: public Base< Rule >
{
template< tao_json_pegtl::apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
internal::state_disable_helper< A, State > s;
if ( Base< Rule >::template match< A, Action, Control >( in, s ) ) {
s.success( st ... );
return true;
}
return false;
}
};
template< typename Rule, template< typename ... > class Action, template< typename ... > class Base = tao_json_pegtl::normal >
struct change_action
: public Base< Rule >
{
template< tao_json_pegtl::apply_mode A, template< typename ... > class, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return Base< Rule >::template match< A, Action, Control >( in, st ... );
}
};
template< template< typename ... > class Action, template< typename ... > class Base >
struct change_both_helper
{
template< typename T > using change_action = change_action< T, Action, Base >;
};
template< typename Rule, typename State, template< typename ... > class Action, template< typename ... > class Base = tao_json_pegtl::normal >
struct change_state_and_action
: public change_state< Rule, State, change_both_helper< Action, Base >::template change_action >
{ };
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,145 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_HTTP_HH
#define TAO_CPP_PEGTL_CONTRIB_HTTP_HH
#include "../rules.hh"
#include "../ascii.hh"
#include "../utf8.hh"
#include "abnf.hh"
#include "uri.hh"
namespace tao_json_pegtl
{
namespace http
{
// HTTP 1.1 grammar according to RFC 7230.
// This grammar is a direct PEG translation of the original HTTP grammar.
// It should be considered experimental -- in case of any issues, in particular
// missing anchor rules for actions, please contact the developers.
using namespace abnf;
using OWS = star< WSP >; // optional whitespace
using RWS = plus< WSP >; // required whitespace
using BWS = OWS; // "bad" whitespace
// cppcheck-suppress constStatement
using obs_text = not_range< 0x00, 0x7F >;
using obs_fold = seq< CRLF, plus< WSP > >;
struct tchar : sor< ALPHA, DIGIT, one< '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~' > > {};
struct token : plus< tchar > {};
struct field_name : token {};
struct field_vchar : sor< VCHAR, obs_text > {};
struct field_content : list< field_vchar, plus< WSP > > {};
struct field_value : star< sor< field_content, obs_fold > > {};
struct header_field : seq< field_name, one< ':' >, OWS, field_value, OWS > {};
struct method : token {};
struct absolute_path : plus< one< '/' >, uri::segment > {};
struct origin_form : seq< absolute_path, uri::opt_query > {};
struct absolute_form : uri::absolute_URI {};
struct authority_form : uri::authority {};
struct asterisk_form : one< '*' > {};
struct request_target : sor< origin_form, absolute_form, authority_form, asterisk_form > {};
struct status_code : rep< 3, DIGIT > {};
struct reason_phrase : star< sor< VCHAR, obs_text, WSP > > {};
struct HTTP_version : if_must< pegtl_string_t( "HTTP/" ), DIGIT, one< '.' >, DIGIT > {};
struct request_line : if_must< method, SP, request_target, SP, HTTP_version, CRLF > {};
struct status_line : if_must< HTTP_version, SP, status_code, SP, reason_phrase, CRLF > {};
struct start_line : sor< request_line, status_line > {};
struct message_body : star< OCTET > {};
struct HTTP_message : seq< start_line, star< header_field, CRLF >, CRLF, opt< message_body > > {};
struct Content_Length : plus< DIGIT > {};
struct uri_host : uri::host {};
struct port : uri::port {};
struct Host : seq< uri_host, opt< one< ':' >, port > > {};
// PEG are different from CFGs! (this replaces ctext and qdtext)
using text = sor< HTAB, range< 0x20, 0x7E >, obs_text >;
struct quoted_pair : if_must< one< '\\' >, sor< VCHAR, obs_text, WSP > > {};
struct quoted_string : if_must< DQUOTE, until< DQUOTE, sor< quoted_pair, text > > > {};
struct transfer_parameter : seq< token, BWS, one< '=' >, BWS, sor< token, quoted_string > > {};
struct transfer_extension : seq< token, star< OWS, one< ';' >, OWS, transfer_parameter > > {};
struct transfer_coding : sor< pegtl_istring_t( "chunked" ),
pegtl_istring_t( "compress" ),
pegtl_istring_t( "deflate" ),
pegtl_istring_t( "gzip" ),
transfer_extension > {};
struct rank : sor< seq< one< '0' >, opt< one< '.' >, rep_opt< 3, DIGIT > > >,
seq< one< '1' >, opt< one< '.' >, rep_opt< 3, one< '0' > > > > > {};
struct t_ranking : seq< OWS, one< ';' >, OWS, one< 'q', 'Q' >, one< '=' >, rank > {};
struct t_codings : sor< pegtl_istring_t( "trailers" ), seq< transfer_coding, opt< t_ranking > > > {};
struct TE : opt< sor< one< ',' >, t_codings >, star< OWS, one< ',' >, opt< OWS, t_codings > > > {};
template< typename T >
using make_comma_list = seq< star< one< ',' >, OWS >, T, star< OWS, one< ',' >, opt< OWS, T > > >;
struct connection_option : token {};
struct Connection : make_comma_list< connection_option > {};
struct Trailer : make_comma_list< field_name > {};
struct Transfer_Encoding : make_comma_list< transfer_coding > {};
struct protocol_name : token {};
struct protocol_version : token {};
struct protocol : seq< protocol_name, opt< one< '/' >, protocol_version > > {};
struct Upgrade : make_comma_list< protocol > {};
struct pseudonym : token {};
struct received_protocol : seq< opt< protocol_name, one< '/' > >, protocol_version > {};
struct received_by : sor< seq< uri_host, opt< one< ':' >, port > >, pseudonym > {};
struct comment : if_must< one< '(' >, until< one< ')' >, sor< comment, quoted_pair, text > > > {};
struct Via : make_comma_list< seq< received_protocol, RWS, received_by, opt< RWS, comment > > > {};
struct http_URI : if_must< pegtl_istring_t( "http://" ), uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {};
struct https_URI : if_must< pegtl_istring_t( "https://" ), uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {};
struct partial_URI : seq< uri::relative_part, uri::opt_query > {};
struct chunk_size : plus< HEXDIG > {};
struct chunk_ext_name : token {};
struct chunk_ext_val : sor< quoted_string, token > {};
struct chunk_ext : star< if_must< one< ';' >, chunk_ext_name, if_must< one< '=' >, chunk_ext_val > > > {};
struct chunk_data : until< at< CRLF >, OCTET > {};
struct chunk : seq< chunk_size, opt< chunk_ext >, CRLF, chunk_data, CRLF > {};
struct last_chunk : seq< plus< one< '0' > >, opt< chunk_ext >, CRLF > {};
struct trailer_part : star< header_field, CRLF > {};
struct chunked_body : seq< until< last_chunk, chunk >, trailer_part, CRLF > {};
} // namespace http
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,89 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_JSON_HH
#define TAO_CPP_PEGTL_CONTRIB_JSON_HH
#include "../rules.hh"
#include "../ascii.hh"
#include "../utf8.hh"
#include "abnf.hh"
namespace tao_json_pegtl
{
namespace json
{
// JSON grammar according to RFC 7159 (for UTF-8 encoded JSON only).
struct ws : one< ' ', '\t', '\n', '\r' > {};
template< typename R, typename P = ws > struct padr : internal::seq< R, internal::star< P > > {};
struct begin_array : padr< one< '[' > > {};
struct begin_object : padr< one< '{' > > {};
struct end_array : one< ']' > {};
struct end_object : one< '}' > {};
struct name_separator : pad< one< ':' >, ws > {};
struct value_separator : padr< one< ',' > > {};
struct false_ : pegtl_string_t( "false" ) {};
struct null : pegtl_string_t( "null" ) {};
struct true_ : pegtl_string_t( "true" ) {};
struct digits : plus< abnf::DIGIT > {};
struct exp : seq< one< 'e', 'E' >, opt< one< '-', '+'> >, must< digits > > {};
struct frac : if_must< one< '.' >, digits > {};
struct int_ : sor< one< '0' >, digits > {};
struct number : seq< opt< one< '-' > >, int_, opt< frac >, opt< exp > > {};
struct xdigit : abnf::HEXDIG {};
struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {};
struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {};
struct escaped : sor< escaped_char, unicode > {};
struct unescaped : utf8::range< 0x20, 0x10FFFF > {};
struct char_ : if_then_else< one< '\\' >, must< escaped >, unescaped > {};
struct string_content : until< at< one< '"' > >, must< char_ > > {};
struct string : seq< one< '"' >, must< string_content >, any >
{
using content = string_content;
};
struct key_content : until< at< one< '"' > >, must< char_ > > {};
struct key : seq< one< '"' >, must< key_content >, any >
{
using content = key_content;
};
struct value;
struct array_element;
struct array_content : opt< list_must< array_element, value_separator > > {};
struct array : seq< begin_array, array_content, must< end_array > >
{
using begin = begin_array;
using end = end_array;
using element = array_element;
using content = array_content;
};
struct member : if_must< key, name_separator, value > {};
struct object_content : opt< list_must< member, value_separator > > {};
struct object : seq< begin_object, object_content, must< end_object > >
{
using begin = begin_object;
using end = end_object;
using element = member;
using content = object_content;
};
struct value : padr< sor< string, number, object, array, false_, true_, null > > {};
struct array_element : seq< value > {};
struct text : seq< star< ws >, value > {};
} // namespace json
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,164 @@
// Copyright (c) 2014-2017 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_RAW_STRING_HH
#define TAO_CPP_PEGTL_CONTRIB_RAW_STRING_HH
#include "../action_input.hh"
#include "../apply_mode.hh"
#include "../nothing.hh"
#include "../internal/must.hh"
#include "../internal/until.hh"
#include "../internal/state.hh"
#include "../internal/skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< char Open, char Intermediate, char Close >
struct raw_string_tag
{ };
template< typename Tag >
struct raw_string_state
{
template< typename Input, typename ... States >
raw_string_state( const Input & in, States && ... )
: byte( in.byte() ),
line( in.line() ),
byte_in_line( in.byte_in_line() ),
size( in.size( 0 ) )
{ }
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
typename std::enable_if< ( ( A == apply_mode::ACTION ) && ( ! is_nothing< Action, Tag >::value ) ) >::type
success( const Input & in, States && ... st ) const
{
using eol_t = typename Input::eol_t;
using action_t = typename Input::action_t;
const auto * const begin = in.begin() - size + in.size( 0 ) + count;
action_t action_in( byte, line, byte_in_line, begin + ( ( * begin ) == eol_t::ch ), in.begin() - count, in.source() );
Action< Tag >::apply( const_cast< const action_t & >( action_in ), st ... );
}
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
typename std::enable_if< ! ( ( A == apply_mode::ACTION ) && ( ! is_nothing< Action, Tag >::value ) ) >::type
success( const Input &, States && ... ) const
{ }
raw_string_state( const raw_string_state & ) = delete;
void operator= ( const raw_string_state & ) = delete;
std::size_t byte;
std::size_t line;
std::size_t byte_in_line;
std::size_t size;
std::size_t count = 0;
};
template< typename Tag, char Open, char Intermediate >
struct raw_string_open
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input >
static bool match( Input & in, raw_string_state< Tag > & ls )
{
if ( in.empty() || ( in.peek_char( 0 ) != Open ) ) {
return false;
}
for ( std::size_t i = 1; i < in.size( i + 1 ); ++i ) {
switch ( const auto c = in.peek_char( i ) ) {
case Open:
ls.count = i + 1;
in.bump( ls.count );
return true;
case Intermediate:
break;
default:
return false;
}
}
return false;
}
};
template< typename Tag, char Intermediate, char Close >
struct raw_string_close
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input >
static bool match( Input & in, const raw_string_state< Tag > & ls )
{
if ( in.size( ls.count ) < ls.count ) {
return false;
}
if ( in.peek_char( 0 ) != Close ) {
return false;
}
if ( in.peek_char( ls.count - 1 ) != Close ) {
return false;
}
for ( std::size_t i = 0; i < ls.count - 2; ++i ) {
if ( in.peek_char( i + 1 ) != Intermediate ) {
return false;
}
}
in.bump( ls.count );
return true;
}
};
template< typename Tag, char Open, char Intermediate >
struct skip_control< raw_string_open< Tag, Open, Intermediate > > : std::true_type {};
template< typename Tag, char Intermediate, char Close >
struct skip_control< raw_string_close< Tag, Intermediate, Close > > : std::true_type {};
} // namespace internal
// raw_string matches Lua-style long literals.
//
// The following description was taken from the Lua documentation
// (see http://www.lua.org/docs.html):
//
// - An "opening long bracket of level n" is defined as an opening square
// bracket followed by n equal signs followed by another opening square
// bracket. So, an opening long bracket of level 0 is written as `[[`,
// an opening long bracket of level 1 is written as `[=[`, and so on.
// - A "closing long bracket" is defined similarly; for instance, a closing
// long bracket of level 4 is written as `]====]`.
// - A "long literal" starts with an opening long bracket of any level and
// ends at the first closing long bracket of the same level. It can
// contain any text except a closing bracket of the same level.
// - Literals in this bracketed form can run for several lines, do not
// interpret any escape sequences, and ignore long brackets of any other
// level.
// - For convenience, when the opening long bracket is immediately followed
// by a newline, the newline is not included in the string.
//
// Note that unlike Lua's long literal, a raw_string is customizable to use
// other characters than `[`, `=` and `]` for matching. Also note that Lua
// introduced newline-specific replacements in Lua 5.2, which we do not
// support on the grammar level.
template< char Open, char Intermediate, char Close, typename Tag = internal::raw_string_tag< Open, Intermediate, Close > >
struct raw_string : internal::state< internal::raw_string_state< Tag >,
internal::raw_string_open< Tag, Open, Intermediate >,
internal::must< internal::until< internal::raw_string_close< Tag, Intermediate, Close > > > >
{
// This is used to bind an action to the content.
using content = Tag;
// This is used for error-reporting when a raw string is not closed properly.
using close = internal::until< internal::raw_string_close< Tag, Intermediate, Close > >;
};
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,180 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_UNESCAPE_HH
#define TAO_CPP_PEGTL_CONTRIB_UNESCAPE_HH
#include <string>
#include <cassert>
#include "../ascii.hh"
#include "../parse_error.hh"
namespace tao_json_pegtl
{
namespace unescape
{
struct state
{
std::string unescaped;
};
// Utility functions for the unescape actions.
inline bool utf8_append_utf32( std::string & string, const unsigned utf32 )
{
if ( utf32 <= 0x7f ) {
string += char( utf32 & 0xff );
return true;
}
if ( utf32 <= 0x7ff ) {
char tmp[] = { char( ( ( utf32 & 0x7c0 ) >> 6 ) | 0xc0 ),
char( ( ( utf32 & 0x03f ) ) | 0x80 ) };
string.append( tmp, sizeof( tmp ) );
return true;
}
if ( utf32 <= 0xffff ) {
char tmp[] = { char( ( ( utf32 & 0xf000 ) >> 12 ) | 0xe0 ),
char( ( ( utf32 & 0x0fc0 ) >> 6 ) | 0x80 ),
char( ( ( utf32 & 0x003f ) ) | 0x80 ) };
string.append( tmp, sizeof( tmp ) );
return true;
}
if ( utf32 <= 0x10ffff ) {
char tmp[] = { char( ( ( utf32 & 0x1c0000 ) >> 18 ) | 0xf0 ),
char( ( ( utf32 & 0x03f000 ) >> 12 ) | 0x80 ),
char( ( ( utf32 & 0x000fc0 ) >> 6 ) | 0x80 ),
char( ( ( utf32 & 0x00003f ) ) | 0x80 ) };
string.append( tmp, sizeof( tmp ) );
return true;
}
return false;
}
// This function MUST only be called for characters matching tao_json_pegtl::ascii::xdigit!
template< typename I >
I unhex_char( const char c )
{
switch ( c ) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
return I( c - '0' );
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
return I( c - 'a' + 10 );
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
return I( c - 'A' + 10 );
}
throw std::runtime_error( "invalid character in unhex" ); // LCOV_EXCL_LINE
}
template< typename I >
I unhex_string( const char * begin, const char * const end )
{
I r = 0;
while ( begin != end ) {
r <<= 4;
r += unhex_char< I >( *begin++ );
}
return r;
}
// Actions for common unescape situations.
struct append_all
{
template< typename Input, typename State >
static void apply( const Input & in, State & st )
{
st.unescaped.append( in.begin(), in.size() );
}
};
// This action MUST be called for a character matching T which MUST be tao_json_pegtl::one< ... >.
template< typename T, char ... Rs >
struct unescape_c
{
template< typename Input, typename State >
static void apply( const Input & in, State & st )
{
assert( in.size() == 1 );
st.unescaped += apply_one( * in.begin(), static_cast< const T * >( nullptr ) );
}
template< char ... Qs >
static char apply_one( const char c, const one< Qs ... > * )
{
static_assert( sizeof ... ( Qs ) == sizeof ... ( Rs ), "size mismatch between escaped characters and their mappings" );
return apply_two( c, { Qs ... }, { Rs ... } );
}
static char apply_two( const char c, const std::initializer_list< char > & q, const std::initializer_list< char > & r )
{
for ( std::size_t i = 0; i < q.size(); ++i ) {
if ( * ( q.begin() + i ) == c ) {
return * ( r.begin() + i );
}
}
throw std::runtime_error( "invalid character in unescape" ); // LCOV_EXCL_LINE
}
};
// See examples/unescape.cc for why the following two actions
// skip the first input character. They also MUST be called
// with non-empty matched inputs!
struct unescape_u
{
template< typename Input, typename State >
static void apply( const Input & in, State & st )
{
assert( ! in.empty() ); // First character MUST be present, usually 'u' or 'U'.
if ( ! utf8_append_utf32( st.unescaped, unhex_string< unsigned >( in.begin() + 1, in.end() ) ) ) {
using exception_t = typename Input::exception_t;
throw exception_t( "invalid escaped unicode code point", in );
}
}
};
struct unescape_x
{
template< typename Input, typename State >
static void apply( const Input & in, State & st )
{
assert( ! in.empty() ); // First character MUST be present, usually 'x'.
st.unescaped += unhex_string< char >( in.begin() + 1, in.end() );
}
};
// The unescape_j action is similar to unescape_u, however unlike
// unescape_u it
// (a) assumes exactly 4 hexdigits per escape sequence,
// (b) accepts multiple consecutive escaped 16-bit values.
// When applied to more than one escape sequence, unescape_j
// translates UTF-16 surrogate pairs in the input into a single
// UTF-8 sequence in st.unescaped, as required for JSON by RFC 7159.
struct unescape_j
{
template< typename Input, typename State >
static void apply( const Input & in, State & st )
{
assert( ( ( in.size() + 1 ) % 6 ) == 0 ); // Expects multiple "\\u1234", starting with the first "u".
for ( const char * b = in.begin() + 1; b < in.end(); b += 6 ) {
const auto c = unhex_string< unsigned >( b, b + 4 );
if ( ( 0xd800 <= c ) && ( c <= 0xdbff ) && ( b + 6 < in.end() ) ) {
const auto d = unhex_string< unsigned >( b + 6, b + 10 );
if ( ( 0xdc00 <= d ) && ( d <= 0xdfff ) ) {
b += 6;
utf8_append_utf32( st.unescaped, ( ( ( c & 0x03ff ) << 10 ) | ( d & 0x03ff ) ) + 0x10000 );
continue;
}
}
utf8_append_utf32( st.unescaped, c );
}
}
};
} // namespace unescape
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,108 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CONTRIB_URI_HH
#define TAO_CPP_PEGTL_CONTRIB_URI_HH
#include "../rules.hh"
#include "../ascii.hh"
#include "../utf8.hh"
#include "abnf.hh"
namespace tao_json_pegtl
{
namespace uri
{
// URI grammar according to RFC 3986.
// This grammar is a direct PEG translation of the original URI grammar.
// It should be considered experimental -- in case of any issues, in particular
// missing anchor rules for actions, please contact the developers.
// Note that this grammar has multiple top-level rules.
using namespace abnf;
using dot = one< '.' >;
using colon = one< ':' >;
struct dec_octet : sor< one< '0' >,
rep_min_max< 1, 2, DIGIT >,
seq< one< '1' >, DIGIT, DIGIT >,
seq< one< '2' >, range< '0', '4' >, DIGIT >,
seq< string< '2', '5' >, range< '0', '5' > > > {};
struct IPv4address : seq< dec_octet, dot, dec_octet, dot, dec_octet, dot, dec_octet > {};
struct h16 : rep_min_max< 1, 4, HEXDIG > {};
struct ls32 : sor< seq< h16, colon, h16 >, IPv4address > {};
struct dcolon : two< ':' > {};
struct IPv6address : sor< seq< rep< 6, h16, colon >, ls32 >,
seq< dcolon, rep< 5, h16, colon >, ls32 >,
seq< opt< h16 >, dcolon, rep< 4, h16, colon >, ls32 >,
seq< opt< h16, opt< colon, h16 > >, dcolon, rep< 3, h16, colon >, ls32 >,
seq< opt< h16, rep_opt< 2, colon, h16 > >, dcolon, rep< 2, h16, colon >, ls32 >,
seq< opt< h16, rep_opt< 3, colon, h16 > >, dcolon, h16, colon, ls32 >,
seq< opt< h16, rep_opt< 4, colon, h16 > >, dcolon, ls32 >,
seq< opt< h16, rep_opt< 5, colon, h16 > >, dcolon, h16 >,
seq< opt< h16, rep_opt< 6, colon, h16 > >, dcolon > > {};
struct gen_delims : one< ':', '/', '?', '#', '[', ']', '@' > {};
struct sub_delims : one< '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' > {};
struct unreserved : sor< ALPHA, DIGIT, one< '-', '.', '_', '~' > > {};
struct reserved : sor< gen_delims, sub_delims > {};
struct IPvFuture : if_must< one< 'v' >, plus< HEXDIG >, dot, plus< sor< unreserved, sub_delims, colon > > > {};
struct IP_literal : if_must< one< '[' >, sor< IPvFuture, IPv6address >, one< ']' > > {};
struct pct_encoded : if_must< one< '%' >, HEXDIG, HEXDIG > {};
struct pchar : sor< unreserved, pct_encoded, sub_delims, one< ':', '@' > > {};
struct query : star< sor< pchar, one< '/', '?' > > > {};
struct fragment : star< sor< pchar, one< '/', '?' > > > {};
struct segment : star< pchar > {};
struct segment_nz : plus< pchar > {};
struct segment_nz_nc : plus< sor< unreserved, pct_encoded, sub_delims, one< '@' > > > {}; // non-zero-length segment without any colon ":"
struct path_abempty : star< one< '/' >, segment > {};
struct path_absolute : seq< one< '/' >, opt< segment_nz, star< one< '/' >, segment > > > {};
struct path_noscheme : seq< segment_nz_nc, star< one< '/' >, segment > > {};
struct path_rootless : seq< segment_nz, star< one< '/' >, segment > > {};
struct path_empty : success {};
struct path : sor< path_noscheme, // begins with a non-colon segment
path_rootless, // begins with a segment
path_absolute, // begins with "/" but not "//"
path_abempty > {}; // begins with "/" or is empty
struct reg_name : star< sor< unreserved, pct_encoded, sub_delims > > {};
struct port : star< DIGIT > {};
struct host : sor< IP_literal, IPv4address, reg_name > {};
struct userinfo : star< sor< unreserved, pct_encoded, sub_delims, colon > > {};
struct authority : seq< opt< userinfo, one< '@' > >, host, opt< colon, port > > {};
struct scheme : seq< ALPHA, star< sor< ALPHA, DIGIT, one< '+', '-', '.' > > > > {};
using dslash = two< '/' >;
using opt_query = opt< if_must< one< '?' >, query > >;
using opt_fragment = opt< if_must< one< '#' >, fragment > >;
struct hier_part : sor< if_must< dslash, authority, path_abempty >, path_rootless, path_absolute, path_empty > {};
struct relative_part : sor< if_must< dslash, authority, path_abempty >, path_noscheme, path_absolute, path_empty > {};
struct relative_ref : seq< relative_part, opt_query, opt_fragment > {};
struct URI : seq< scheme, one< ':' >, hier_part, opt_query, opt_fragment > {};
struct URI_reference : sor< URI, relative_ref > {};
struct absolute_URI : seq< scheme, one< ':' >, hier_part, opt_query > {};
} // namespace uri
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,29 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CR_CRLF_EOL_HH
#define TAO_CPP_PEGTL_CR_CRLF_EOL_HH
namespace tao_json_pegtl
{
struct cr_crlf_eol
{
static constexpr int ch = '\r';
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 2 ) };
if ( p.second ) {
if ( in.peek_char() == '\r' ) {
in.bump_to_next_line( 1 + ( ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) );
p.first = true;
}
}
return p;
}
};
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,29 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CR_EOL_HH
#define TAO_CPP_PEGTL_CR_EOL_HH
namespace tao_json_pegtl
{
struct cr_eol
{
static constexpr int ch = '\r';
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 1 ) };
if ( p.second ) {
if ( in.peek_char() == '\r' ) {
in.bump_to_next_line();
p.first = true;
}
}
return p;
}
};
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,29 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_CRLF_EOL_HH
#define TAO_CPP_PEGTL_CRLF_EOL_HH
namespace tao_json_pegtl
{
struct crlf_eol
{
static constexpr int ch = '\n';
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 2 ) };
if ( p.second > 1 ) {
if ( ( in.peek_char() == '\r' ) && ( in.peek_char( 1 ) == '\n' ) ) {
in.bump_to_next_line( 2 );
p.first = true;
}
}
return p;
}
};
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_EOL_HH
#define TAO_CPP_PEGTL_EOL_HH
#include <utility>
#include <cstdlib>
namespace tao_json_pegtl
{
using eol_pair = std::pair< bool, std::size_t >;
} // namespace tao_json_pegtl
#include "lf_eol.hh"
#include "cr_eol.hh"
#include "crlf_eol.hh"
#include "lf_crlf_eol.hh"
#include "cr_crlf_eol.hh"
#endif

View File

@ -0,0 +1,43 @@
// Copyright (c) 2015-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_FILE_PARSER_HH
#define TAO_CPP_PEGTL_FILE_PARSER_HH
#include "read_parser.hh"
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
#include <unistd.h> // Required for _POSIX_MAPPED_FILES
#endif
#if defined(_POSIX_MAPPED_FILES)
#include "mmap_parser.hh"
#endif
namespace tao_json_pegtl
{
#if defined(_POSIX_MAPPED_FILES)
using file_parser = mmap_parser;
template< typename Eol >
using basic_file_parser = basic_mmap_parser< Eol >;
#else
using file_parser = read_parser;
template< typename Eol >
using basic_file_parser = basic_read_parser< Eol >;
#endif
template< typename Rule, template< typename ... > class Action = nothing, template< typename ... > class Control = normal, typename ... States >
bool parse_file( const std::string & filename, States && ... st )
{
return file_parser( filename ).parse< Rule, Action, Control >( st ... );
}
template< typename Rule, template< typename ... > class Action = nothing, template< typename ... > class Control = normal, typename Outer, typename ... States >
bool parse_file_nested( Outer & oi, const std::string & filename, States && ... st )
{
return basic_file_parser< typename Outer::eol >( filename ).template parse_nested< Rule, Action, Control >( oi, st ... );
}
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,34 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INPUT_ERROR_HH
#define TAO_CPP_PEGTL_INPUT_ERROR_HH
#include <sstream>
#include <stdexcept>
#include <cerrno>
namespace tao_json_pegtl
{
struct input_error
: std::runtime_error
{
input_error( const std::string & message, const int in_errorno )
: std::runtime_error( message ),
errorno( in_errorno )
{ }
int errorno;
};
#define TAO_CPP_PEGTL_THROW_INPUT_ERROR( MESSAGE ) \
do { \
const int errorno = errno; \
std::ostringstream oss; \
oss << "pegtl: " << MESSAGE << " errno " << errorno; \
throw tao_json_pegtl::input_error( oss.str(), errorno ); \
} while ( false )
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ACTION_HH
#define TAO_CPP_PEGTL_INTERNAL_ACTION_HH
#include "skip_control.hh"
#include "seq.hh"
#include "rule_match_three.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< template< typename ... > class Action, typename ... Rules >
struct action
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules ... >;
template< apply_mode A, template< typename ... > class, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return rule_match_three< seq< Rules ... >, A, Action, Control >::match( in, st ... );
}
};
template< template< typename ... > class Action, typename ... Rules >
struct skip_control< action< Action, Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,59 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ANY_HH
#define TAO_CPP_PEGTL_INTERNAL_ANY_HH
#include "skip_control.hh"
#include "peek_char.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Peek > struct any;
template< typename Peek >
struct skip_control< any< Peek > > : std::true_type {};
template<>
struct any< peek_char >
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< typename Input >
static bool match( Input & in )
{
if ( ! in.empty() ) {
in.bump();
return true;
}
return false;
}
};
template< typename Peek >
struct any
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< typename Input >
static bool match( Input & in )
{
if ( ! in.empty() ) {
if ( const auto t = Peek::peek( in ) ) {
in.bump( t.size );
return true;
}
}
return false;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,43 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_AT_HH
#define TAO_CPP_PEGTL_INTERNAL_AT_HH
#include "skip_control.hh"
#include "trivial.hh"
#include "rule_conjunction.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules > struct at;
template< typename ... Rules >
struct skip_control< at< Rules ... > > : std::true_type {};
template<>
struct at<>
: trivial< true > {};
template< typename ... Rules >
struct at
{
using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules ... >;
template< apply_mode, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
return rule_conjunction< Rules ... >::template match< apply_mode::NOTHING, Action, Control >( in, st ... );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,50 @@
// Copyright (c) 2015-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_BUMP_UTIL_HH
#define TAO_CPP_PEGTL_INTERNAL_BUMP_UTIL_HH
#include <cstddef>
#include <type_traits>
#include "result_on_found.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< bool > struct bump_impl;
template<> struct bump_impl< true >
{
template< typename Input >
static void bump( Input & in, const std::size_t count )
{
in.bump( count );
}
};
template<> struct bump_impl< false >
{
template< typename Input >
static void bump( Input & in, const std::size_t count )
{
in.bump_in_this_line( count );
}
};
template< bool ... > struct bool_list {};
template< bool ... Bs > using bool_and = std::is_same< bool_list< Bs..., true >, bool_list< true, Bs... > >;
template< result_on_found R, typename Input, typename Char, Char ... Cs >
void bump( Input & in, const std::size_t count )
{
using eol_t = typename Input::eol_t;
bump_impl< bool_and< ( Cs != eol_t::ch ) ... >::value != bool( R ) >::bump( in, count );
}
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,45 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_BYTES_HH
#define TAO_CPP_PEGTL_INTERNAL_BYTES_HH
#include "skip_control.hh"
#include "../analysis/counted.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Num >
struct bytes
{
using analyze_t = analysis::counted< analysis::rule_type::ANY, Num >;
// suppress warning with GCC 4.7
template< typename T1, typename T2 >
static inline bool dummy_greater_or_equal( const T1 a, const T2 b )
{
return a >= b;
}
template< typename Input >
static bool match( Input & in )
{
if ( dummy_greater_or_equal( in.size( Num ), Num ) ) {
in.bump( Num );
return true;
}
return false;
}
};
template< unsigned Num >
struct skip_control< bytes< Num > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_CONTROL_HH
#define TAO_CPP_PEGTL_INTERNAL_CONTROL_HH
#include "skip_control.hh"
#include "seq.hh"
#include "rule_match_three.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< template< typename ... > class Control, typename ... Rules >
struct control
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules ... >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return rule_match_three< seq< Rules ... >, A, Action, Control >::match( in, st ... );
}
};
template< template< typename ... > class Control, typename ... Rules >
struct skip_control< control< Control, Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,43 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_CSTREAM_READER_HH
#define TAO_CPP_PEGTL_INTERNAL_CSTREAM_READER_HH
#include <cstdio>
#include <cstddef>
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct cstream_reader
{
explicit
cstream_reader( std::FILE * s )
: m_cstream( s )
{ }
std::size_t operator() ( char * buffer, const std::size_t length )
{
if ( const auto r = std::fread( buffer, 1, length, m_cstream ) ) {
return r;
}
if ( std::feof( m_cstream ) != 0 ) {
return 0;
}
// Please contact us if you know how to provoke the following exception.
// The example on cppreference.com doesn't work, at least not on Mac OS X.
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "error in fread() from cstream" ); // LCOV_EXCL_LINE
}
std::FILE * m_cstream;
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,45 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_CSTRING_READER_HH
#define TAO_CPP_PEGTL_INTERNAL_CSTRING_READER_HH
#include <cassert>
#include <cstddef>
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct cstring_reader
{
explicit
cstring_reader( const char * zero_terminated )
: m_cstring( zero_terminated )
{
assert( m_cstring );
}
std::size_t operator() ( char * buffer, const std::size_t length )
{
std::size_t i = 0;
char c;
while ( ( i < length ) && ( ( c = m_cstring[ i ] ) != 0 ) ) {
*buffer++ = c;
++i;
}
m_cstring += i;
return i;
}
const char * m_cstring;
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DEMANGLE_HH
#define TAO_CPP_PEGTL_INTERNAL_DEMANGLE_HH
#include <string>
#include <typeinfo>
#if defined(__GLIBCXX__)
#include "demangle_cxxabi.hh"
#elif defined(__has_include)
#if __has_include(<cxxabi.h>)
#include "demangle_cxxabi.hh"
#else
#include "demangle_nop.hh"
#endif
#else
#include "demangle_nop.hh"
#endif
namespace tao_json_pegtl
{
namespace internal
{
template< typename T >
std::string demangle()
{
return demangle( typeid( T ).name() );
}
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,26 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DEMANGLE_CXXABI_HH
#define TAO_CPP_PEGTL_INTERNAL_DEMANGLE_CXXABI_HH
#include <string>
#include <memory>
#include <cstdlib>
#include <cxxabi.h>
namespace tao_json_pegtl
{
namespace internal
{
inline std::string demangle( const char * symbol )
{
const std::unique_ptr< char, decltype( & std::free ) > demangled( abi::__cxa_demangle( symbol, nullptr, nullptr, nullptr ), & std::free );
return demangled ? demangled.get() : symbol;
}
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DEMANGLE_NOP_HH
#define TAO_CPP_PEGTL_INTERNAL_DEMANGLE_NOP_HH
#include <string>
namespace tao_json_pegtl
{
namespace internal
{
inline std::string demangle( const char * symbol )
{
return symbol;
}
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DISABLE_HH
#define TAO_CPP_PEGTL_INTERNAL_DISABLE_HH
#include "skip_control.hh"
#include "seq.hh"
#include "rule_match_three.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules >
struct disable
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules ... >;
template< apply_mode, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return rule_match_three< seq< Rules ... >, apply_mode::NOTHING, Action, Control >::match( in, st ... );
}
};
template< typename ... Rules >
struct skip_control< disable< Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,34 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DISCARD_HH
#define TAO_CPP_PEGTL_INTERNAL_DISCARD_HH
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct discard
{
using analyze_t = analysis::generic< analysis::rule_type::OPT >;
template< typename Input >
static bool match( Input & in )
{
in.discard();
return true;
}
};
template<>
struct skip_control< discard > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,40 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_DISCARD_IF_HH
#define TAO_CPP_PEGTL_INTERNAL_DISCARD_IF_HH
#include "skip_control.hh"
#include "seq.hh"
#include "rule_match_three.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules >
struct discard_if
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules ... >;
template< apply_mode, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
if ( rule_match_three< seq< Rules ... >, apply_mode::ACTION, Action, Control >::match( in, st ... ) ) {
in.discard();
return true;
}
return false;
}
};
template< typename ... Rules >
struct skip_control< discard_if< Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ENABLE_HH
#define TAO_CPP_PEGTL_INTERNAL_ENABLE_HH
#include "skip_control.hh"
#include "seq.hh"
#include "rule_match_three.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules >
struct enable
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules ... >;
template< apply_mode, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return rule_match_three< seq< Rules ... >, apply_mode::ACTION, Action, Control >::match( in, st ... );
}
};
template< typename ... Rules >
struct skip_control< enable< Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,33 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_EOF_HH
#define TAO_CPP_PEGTL_INTERNAL_EOF_HH
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct eof
{
using analyze_t = analysis::generic< analysis::rule_type::OPT >;
template< typename Input >
static bool match( Input & in )
{
return in.empty();
}
};
template<>
struct skip_control< eof > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,34 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_EOL_HH
#define TAO_CPP_PEGTL_INTERNAL_EOL_HH
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct eol
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< typename Input >
static bool match( Input & in )
{
using eol_t = typename Input::eol_t;
return eol_t::match( in ).first;
}
};
template<>
struct skip_control< eol > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,108 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_EOL_IMPL_HH
#define TAO_CPP_PEGTL_INTERNAL_EOL_IMPL_HH
#include <utility>
#include "../eol_mode.hh"
namespace tao_json_pegtl
{
namespace internal
{
using eol_pair = std::pair< bool, std::size_t >;
template< eol_mode EOL > struct eol_impl;
template<> struct eol_impl< eol_mode::LF_ONLY >
{
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 1 ) };
if ( p.second ) {
if ( in.peek_char() == '\n' ) {
in.bump_to_next_line();
p.first = true;
}
}
return p;
}
};
template<> struct eol_impl< eol_mode::CR_ONLY >
{
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 1 ) };
if ( p.second ) {
if ( in.peek_char() == '\r' ) {
in.bump_to_next_line();
p.first = true;
}
}
return p;
}
};
template<> struct eol_impl< eol_mode::CRLF_ONLY >
{
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 2 ) };
if ( p.second > 1 ) {
if ( ( in.peek_char() == '\r' ) && ( in.peek_char( 1 ) == '\n' ) ) {
in.bump_to_next_line( 2 );
p.first = true;
}
}
return p;
}
};
template<> struct eol_impl< eol_mode::LF_WITH_CRLF >
{
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 2 ) };
if ( p.second ) {
const auto a = in.peek_char();
if ( a == '\n' ) {
in.bump_to_next_line();
p.first = true;
}
else if ( ( a == '\r' ) && ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) {
in.bump_to_next_line( 2 );
p.first = true;
}
}
return p;
}
};
template<> struct eol_impl< eol_mode::CR_WITH_CRLF >
{
template< typename Input >
static eol_pair match( Input & in )
{
eol_pair p = { false, in.size( 2 ) };
if ( p.second ) {
if ( in.peek_char() == '\r' ) {
in.bump_to_next_line( 1 + ( ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) );
p.first = true;
}
}
return p;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,35 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_EOLF_HH
#define TAO_CPP_PEGTL_INTERNAL_EOLF_HH
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct eolf
{
using analyze_t = analysis::generic< analysis::rule_type::OPT >;
template< typename Input >
static bool match( Input & in )
{
using eol_t = typename Input::eol_t;
const auto p = eol_t::match( in );
return p.first || ( ! p.second );
}
};
template<>
struct skip_control< eolf > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,85 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_FILE_MAPPER_HH
#define TAO_CPP_PEGTL_INTERNAL_FILE_MAPPER_HH
#include <unistd.h>
#include <sys/mman.h>
#include "file_opener.hh"
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
class file_mapper
{
public:
explicit
file_mapper( const std::string & filename )
: file_mapper( file_opener( filename ) )
{ }
explicit
file_mapper( const file_opener & reader )
: m_size( reader.size() ),
m_data( static_cast< const char * >( ::mmap( nullptr, m_size, PROT_READ, MAP_FILE | MAP_PRIVATE, reader.m_fd, 0 ) ) )
{
if ( m_size && ( intptr_t( m_data ) == -1 ) ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to mmap() file " << reader.m_source << " descriptor " << reader.m_fd );
}
}
~file_mapper()
{
::munmap( const_cast< char * >( m_data ), m_size ); // Legacy C interface requires pointer-to-mutable but does not write through the pointer.
}
file_mapper( const file_mapper & ) = delete;
void operator= ( const file_mapper & ) = delete;
bool empty() const
{
return m_size == 0;
}
std::size_t size() const
{
return m_size;
}
using iterator = const char *;
using const_iterator = const char *;
iterator data() const
{
return m_data;
}
iterator begin() const
{
return m_data;
}
iterator end() const
{
return m_data + m_size;
}
std::string string() const
{
return std::string( m_data, m_size );
}
private:
const std::size_t m_size;
const char * const m_data;
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,65 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_FILE_OPENER_HH
#define TAO_CPP_PEGTL_INTERNAL_FILE_OPENER_HH
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utility>
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct file_opener
{
explicit
file_opener( std::string filename )
: m_source( std::move( filename ) ),
m_fd( open() )
{ }
~file_opener()
{
::close( m_fd );
}
file_opener( const file_opener & ) = delete;
void operator= ( const file_opener & ) = delete;
std::size_t size() const
{
struct stat st;
errno = 0;
if ( ::fstat( m_fd, & st ) < 0 ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to fstat() file " << m_source << " descriptor " << m_fd );
}
return std::size_t( st.st_size );
}
const std::string m_source;
const int m_fd;
private:
int open() const
{
errno = 0;
const int fd = ::open( m_source.c_str(), O_RDONLY );
if ( fd >= 0 ) {
return fd;
}
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to open() file " << m_source << " for reading" );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,83 @@
// Copyright (c) 2014-2017 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_FILE_READER_HH
#define TAO_CPP_PEGTL_INTERNAL_FILE_READER_HH
#include <cstdio>
#include <memory>
#include <string>
#include <utility>
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
class file_reader
{
public:
explicit
file_reader( std::string filename )
: m_source( std::move( filename ) ),
m_file( open(), & std::fclose )
{ }
file_reader( const file_reader & ) = delete;
void operator= ( const file_reader & ) = delete;
std::size_t size() const
{
errno = 0;
if ( std::fseek( m_file.get(), 0, SEEK_END ) != 0 ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to end of file " << m_source ); // LCOV_EXCL_LINE
}
errno = 0;
const auto s = std::ftell( m_file.get() );
if ( s < 0 ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to ftell() file size of file " << m_source ); // LCOV_EXCL_LINE
}
errno = 0;
if ( std::fseek( m_file.get(), 0, SEEK_SET ) != 0 ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to beginning of file " << m_source ); // LCOV_EXCL_LINE
}
return s;
}
std::string read() const
{
std::string nrv;
nrv.resize( size() );
errno = 0;
if ( ( nrv.size() != 0 ) && ( std::fread( & nrv[ 0 ], nrv.size(), 1, m_file.get() ) != 1 ) ) {
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to fread() file " << m_source << " size " << nrv.size() ); // LCOV_EXCL_LINE
}
return nrv;
}
private:
const std::string m_source;
const std::unique_ptr< std::FILE, decltype( & std::fclose ) > m_file;
std::FILE * open() const
{
errno = 0;
#ifdef _WIN32
std::FILE* file;
if ( ::fopen_s( & file, m_source.c_str(), "rb" ) == 0 )
#else
if ( auto * file = std::fopen( m_source.c_str(), "rb" ) )
#endif
{
return file;
}
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "unable to fopen() file " << m_source << " for reading" );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,21 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_IF_MUST_HH
#define TAO_CPP_PEGTL_INTERNAL_IF_MUST_HH
#include "seq.hh"
#include "must.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Cond, typename ... Thens >
using if_must = seq< Cond, must< Thens ... > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,21 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_IF_MUST_ELSE_HH
#define TAO_CPP_PEGTL_INTERNAL_IF_MUST_ELSE_HH
#include "if_then_else.hh"
#include "must.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Cond, typename Then, typename Else >
using if_must_else = if_then_else< Cond, must< Then >, must< Else > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,42 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_IF_THEN_ELSE_HH
#define TAO_CPP_PEGTL_INTERNAL_IF_THEN_ELSE_HH
#include "sor.hh"
#include "seq.hh"
#include "not_at.hh"
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Cond, typename Then, typename Else >
struct if_then_else
{
using analyze_t = analysis::generic< analysis::rule_type::SOR, seq< Cond, Then >, seq< not_at< Cond >, Else > >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
if ( Control< Cond >::template match< A, Action, Control >( in, st ... ) ) {
return m( Control< Then >::template match< A, Action, Control >( in, st ... ) );
}
return m( Control< Else >::template match< A, Action, Control >( in, st ... ) );
}
};
template< typename Cond, typename Then, typename Else >
struct skip_control< if_then_else< Cond, Then, Else > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,67 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_INPUT_DATA_HH
#define TAO_CPP_PEGTL_INTERNAL_INPUT_DATA_HH
#include <cstdlib>
namespace tao_json_pegtl
{
namespace internal
{
struct input_data
{
input_data( const std::size_t in_byte, const std::size_t in_line, const std::size_t in_byte_in_line, const char * in_begin, const char * in_end, const char * in_source )
: byte( in_byte ),
line( in_line ),
byte_in_line( in_byte_in_line ),
begin( in_begin ),
end( in_end ),
source( in_source )
{ }
std::size_t byte;
std::size_t line;
std::size_t byte_in_line;
const char * begin;
const char * end;
const char * source;
void bump( const std::size_t count, const int ch )
{
for ( std::size_t i = 0; i < count; ++i ) {
if ( begin[ i ] == ch ) {
++line;
byte_in_line = 0;
}
else {
++byte_in_line;
}
}
begin += count;
byte += count;
}
void bump_in_this_line( const std::size_t count )
{
byte += count;
begin += count;
byte_in_line += count;
}
void bump_to_next_line( const std::size_t count )
{
++line;
byte += count;
begin += count;
byte_in_line = 0;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,89 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_INPUT_MARK_HH
#define TAO_CPP_PEGTL_INTERNAL_INPUT_MARK_HH
#include "input_data.hh"
namespace tao_json_pegtl
{
namespace internal
{
class input_mark
{
public:
explicit
input_mark( input_data & i )
: m_byte( i.byte ),
m_line( i.line ),
m_byte_in_line( i.byte_in_line ),
m_begin( i.begin ),
m_input( & i )
{ }
input_mark( input_mark && i ) noexcept
: m_byte( i.m_byte ),
m_line( i.m_line ),
m_byte_in_line( i.m_byte_in_line ),
m_begin( i.m_begin ),
m_input( i.m_input )
{
i.m_input = nullptr;
}
~input_mark()
{
if ( m_input != nullptr ) {
m_input->byte = m_byte;
m_input->line = m_line;
m_input->byte_in_line = m_byte_in_line;
m_input->begin = m_begin;
}
}
input_mark( const input_mark & ) = delete;
void operator= ( const input_mark & ) = delete;
bool operator() ( const bool result )
{
if ( result ) {
m_input = nullptr;
return true;
}
return false;
}
std::size_t byte() const
{
return m_byte;
}
std::size_t line() const
{
return m_line;
}
std::size_t byte_in_line() const
{
return m_byte_in_line;
}
const char * begin() const
{
return m_begin;
}
private:
const std::size_t m_byte;
const std::size_t m_line;
const std::size_t m_byte_in_line;
const char * const m_begin;
input_data * m_input;
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,29 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_INPUT_PAIR_HH
#define TAO_CPP_PEGTL_INTERNAL_INPUT_PAIR_HH
namespace tao_json_pegtl
{
namespace internal
{
template< typename Data >
struct input_pair
{
Data data;
unsigned char size;
using data_t = Data;
explicit operator bool () const
{
return size > 0;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,42 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ISTREAM_READER_HH
#define TAO_CPP_PEGTL_INTERNAL_ISTREAM_READER_HH
#include <istream>
#include "../input_error.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct istream_reader
{
explicit
istream_reader( std::istream & s )
: m_istream( s )
{ }
std::size_t operator() ( char * buffer, const std::size_t length )
{
m_istream.read( buffer, length );
if ( const auto r = m_istream.gcount() ) {
return r;
}
if ( m_istream.eof() ) {
return 0;
}
TAO_CPP_PEGTL_THROW_INPUT_ERROR( "error in istream.read()" );
}
std::istream & m_istream;
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,89 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ISTRING_HH
#define TAO_CPP_PEGTL_INTERNAL_ISTRING_HH
#include <type_traits>
#include "result_on_found.hh"
#include "skip_control.hh"
#include "bump_util.hh"
#include "trivial.hh"
#include "../analysis/counted.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< char C >
using is_alpha = std::integral_constant< bool, ( ( 'a' <= C ) && ( C <= 'z' ) ) || ( ( 'A' <= C ) && ( C <= 'Z' ) ) >;
template< char C, bool A = is_alpha< C >::value > struct ichar_equal;
template< char C > struct ichar_equal< C, true >
{
static bool match( const char c )
{
return ( C | 0x20 ) == ( c | 0x20 );
}
};
template< char C > struct ichar_equal< C, false >
{
static bool match( const char c )
{
return c == C;
}
};
template< char ... Cs > struct istring_equal;
template<> struct istring_equal<>
{
static bool match( const char * )
{
return true;
}
};
template< char C, char ... Cs > struct istring_equal< C, Cs ... >
{
static bool match( const char * r )
{
return ichar_equal< C >::match( * r ) && istring_equal< Cs ... >::match( r + 1 );
}
};
template< char ... Cs > struct istring;
template< char ... Cs >
struct skip_control< istring< Cs ... > > : std::true_type {};
template<> struct istring<>
: trivial< true > {};
template< char ... Cs >
struct istring
{
using analyze_t = analysis::counted< analysis::rule_type::ANY, sizeof ... ( Cs ) >;
template< typename Input >
static bool match( Input & in )
{
if ( in.size( sizeof ... ( Cs ) ) >= sizeof ... ( Cs ) ) {
if ( istring_equal< Cs ... >::match( in.begin() ) ) {
bump< result_on_found::SUCCESS, Input, char, Cs ... >( in, sizeof ... ( Cs ) );
return true;
}
}
return false;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,21 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_LIST_HH
#define TAO_CPP_PEGTL_INTERNAL_LIST_HH
#include "seq.hh"
#include "star.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Sep >
using list = seq< Rule, star< Sep, Rule > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_LIST_MUST_HH
#define TAO_CPP_PEGTL_INTERNAL_LIST_MUST_HH
#include "seq.hh"
#include "star.hh"
#include "must.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Sep >
using list_must = seq< Rule, star< Sep, must< Rule > > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_LIST_TAIL_HH
#define TAO_CPP_PEGTL_INTERNAL_LIST_TAIL_HH
#include "seq.hh"
#include "list.hh"
#include "opt.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Sep >
using list_tail = seq< list< Rule, Sep >, opt< Sep > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,24 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_LIST_TAIL_PAD_HH
#define TAO_CPP_PEGTL_INTERNAL_LIST_TAIL_PAD_HH
#include "seq.hh"
#include "list.hh"
#include "pad.hh"
#include "opt.hh"
#include "star.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Sep, typename Pad >
using list_tail_pad = seq< list< Rule, pad< Sep, Pad > >, opt< star< Pad >, Sep > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,46 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_MINUS_HH
#define TAO_CPP_PEGTL_INTERNAL_MINUS_HH
#include "skip_control.hh"
#include "../apply_mode.hh"
#include "../memory_input.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename M, typename S >
struct minus
{
using analyze_t = typename M::analyze_t; // NOTE: S is currently ignored for analyze().
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
if ( ! Control< M >::template match< A, Action, Control >( in, st ... ) ) {
return false;
}
using memory_t = typename Input::memory_t;
memory_t i2( m, in.data() );
if ( ! Control< S >::template match< apply_mode::NOTHING, Action, Control >( i2, st ... ) ) {
return m( true );
}
return m( ! i2.empty() );
}
};
template< typename M, typename S >
struct skip_control< minus< M, S > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,49 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_MUST_HH
#define TAO_CPP_PEGTL_INTERNAL_MUST_HH
#include "seq.hh"
#include "raise.hh"
#include "skip_control.hh"
namespace tao_json_pegtl
{
namespace internal
{
// The general case simply applies must<> to each member of the
// 'Rules' parameter pack individually, below is the specialization
// which implements the case for a single rule.
template< typename ... Rules >
struct must
: seq< must< Rules > ... > {};
// While in theory the implementation for a single rule could
// be simplified to must< Rule > = sor< Rule, raise< Rule > >, this
// would result in some unnecessary run-time overhead.
template< typename Rule >
struct must< Rule >
{
using analyze_t = typename Rule::analyze_t;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
if ( ! Control< Rule >::template match< A, Action, Control >( in, st ... ) ) {
raise< Rule >::template match< A, Action, Control >( in, st ... );
}
return true;
}
};
template< typename ... Rules >
struct skip_control< must< Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,43 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_NOT_AT_HH
#define TAO_CPP_PEGTL_INTERNAL_NOT_AT_HH
#include "trivial.hh"
#include "skip_control.hh"
#include "rule_conjunction.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules > struct not_at;
template< typename ... Rules >
struct skip_control< not_at< Rules ... > > : std::true_type {};
template<>
struct not_at<>
: trivial< false > {};
template< typename ... Rules >
struct not_at
{
using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules ... >;
template< apply_mode, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
return ! rule_conjunction< Rules ... >::template match< apply_mode::NOTHING, Action, Control >( in, st ... );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,73 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_ONE_HH
#define TAO_CPP_PEGTL_INTERNAL_ONE_HH
#include <utility>
#include <algorithm>
#include "bump_util.hh"
#include "skip_control.hh"
#include "result_on_found.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Char >
bool contains( const Char c, const std::initializer_list< Char > & l )
{
return std::find( l.begin(), l.end(), c ) != l.end();
}
template< result_on_found R, typename Peek, typename Peek::data_t ... Cs >
struct one
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< typename Input >
static bool match( Input & in )
{
if ( ! in.empty() ) {
if ( const auto t = Peek::peek( in ) ) {
if ( contains( t.data, { Cs ... } ) == bool( R ) ) {
bump< R, Input, typename Peek::data_t, Cs ... >( in, t.size );
return true;
}
}
}
return false;
}
};
template< result_on_found R, typename Peek, typename Peek::data_t C >
struct one< R, Peek, C >
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< typename Input >
static bool match( Input & in )
{
if ( ! in.empty() ) {
if ( const auto t = Peek::peek( in ) ) {
if ( ( t.data == C ) == bool( R ) ) {
bump< R, Input, typename Peek::data_t, C >( in, t.size );
return true;
}
}
}
return false;
}
};
template< result_on_found R, typename Peek, typename Peek::data_t ... Cs >
struct skip_control< one< R, Peek, Cs ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,49 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_OPT_HH
#define TAO_CPP_PEGTL_INTERNAL_OPT_HH
#include <type_traits>
#include "skip_control.hh"
#include "rule_match_three.hh"
#include "seq.hh"
#include "trivial.hh"
#include "../apply_mode.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules > struct opt;
template< typename ... Rules >
struct skip_control< opt< Rules ... > > : std::true_type {};
template<>
struct opt<>
: trivial< true > {};
template< typename ... Rules >
struct opt
{
using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules ... >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
if ( ! in.empty() ) {
rule_match_three< seq< Rules ... >, A, Action, Control >::match( in, st ... );
}
return true;
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,21 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PAD_HH
#define TAO_CPP_PEGTL_INTERNAL_PAD_HH
#include "seq.hh"
#include "star.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Pad1, typename Pad2 = Pad1 >
using pad = seq< star< Pad1 >, Rule, star< Pad2 > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PAD_OPT_HH
#define TAO_CPP_PEGTL_INTERNAL_PAD_OPT_HH
#include "seq.hh"
#include "opt.hh"
#include "star.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename Rule, typename Pad >
using pad_opt = seq< star< Pad >, opt< Rule, star< Pad > > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,31 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PEEK_CHAR_HH
#define TAO_CPP_PEGTL_INTERNAL_PEEK_CHAR_HH
#include <cstddef>
#include "input_pair.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct peek_char
{
using data_t = char;
using pair_t = input_pair< char >;
template< typename Input >
static pair_t peek( Input & in, const std::size_t o = 0 )
{
return { in.peek_char( o ), 1 };
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,48 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PEEK_UTF16_HH
#define TAO_CPP_PEGTL_INTERNAL_PEEK_UTF16_HH
#include <type_traits>
#include "input_pair.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct peek_utf16
{
using data_t = char32_t;
using pair_t = input_pair< char32_t >;
using short_t = std::make_unsigned< char16_t >::type;
static_assert( sizeof( short_t ) == 2, "expected size 2 for 16bit value" );
static_assert( sizeof( char16_t ) == 2, "expected size 2 for 16bit value" );
template< typename Input >
static pair_t peek( Input & in )
{
const std::size_t s = in.size( 4 );
if ( s >= 2 ) {
const char32_t t = * reinterpret_cast< const short_t * >( in.begin() );
if ( ( t < 0xd800 ) || ( t > 0xdbff ) || ( s < 4 ) ) {
return { t, 2 };
}
const char32_t u = * reinterpret_cast< const short_t * >( in.begin() + 2 );
if ( ( u < 0xdc00 ) || ( u > 0xdfff ) ) {
return { t, 2 };
}
return { ( ( ( t & 0x03ff ) << 10 ) | ( u & 0x03ff ) ) + 0x10000, 4 };
}
return { 0, 0 };
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,47 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PEEK_UTF32_HH
#define TAO_CPP_PEGTL_INTERNAL_PEEK_UTF32_HH
#include <cstddef>
#include "input_pair.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct peek_utf32
{
using data_t = char32_t;
using pair_t = input_pair< char32_t >;
static_assert( sizeof( char32_t ) == 4, "expected size 4 for 32bit value" );
// suppress warning with GCC 4.7
template< typename T >
static inline bool dummy_less_or_equal( const T a, const T b )
{
return a <= b;
}
template< typename Input >
static pair_t peek( Input & in )
{
const std::size_t s = in.size( 4 );
if ( s >= 4 ) {
const char32_t t = * reinterpret_cast< const char32_t * >( in.begin() );
if ( dummy_less_or_equal< char32_t >( 0, t ) && dummy_less_or_equal< char32_t >( t, 0x10ffff ) ) {
return { t, 4 };
}
}
return { 0, 0 };
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,82 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PEEK_UTF8_HH
#define TAO_CPP_PEGTL_INTERNAL_PEEK_UTF8_HH
#include "input_pair.hh"
namespace tao_json_pegtl
{
namespace internal
{
struct peek_utf8
{
using data_t = char32_t;
using pair_t = input_pair< char32_t >;
template< typename Input >
static pair_t peek( Input & in )
{
char32_t c0 = in.peek_byte();
if ( ( c0 & 0x80 ) == 0 ) {
return { c0, 1 };
}
if ( ( c0 & 0xE0 ) == 0xC0 ) {
if ( in.size( 2 ) >= 2 ) {
const char32_t c1 = in.peek_byte( 1 );
if ( ( c1 & 0xC0 ) == 0x80 ) {
c0 &= 0x1F;
c0 <<= 6;
c0 |= ( c1 & 0x3F );
if ( c0 >= 0x80 ) {
return { c0, 2 };
}
}
}
}
else if ( ( c0 & 0xF0 ) == 0xE0 ) {
if ( in.size( 3 ) >= 3 ) {
const char32_t c1 = in.peek_byte( 1 );
const char32_t c2 = in.peek_byte( 2 );
if( ( ( c1 & 0xC0 ) == 0x80 ) && ( ( c2 & 0xC0 ) == 0x80 ) ) {
c0 &= 0x0F;
c0 <<= 6;
c0 |= ( c1 & 0x3F );
c0 <<= 6;
c0 |= ( c2 & 0x3F );
if ( c0 >= 0x800 ) {
return { c0, 3 };
}
}
}
}
else if ( ( c0 & 0xF8 ) == 0xF0 ) {
if ( in.size( 4 ) >= 4 ) {
const char32_t c1 = in.peek_byte( 1 );
const char32_t c2 = in.peek_byte( 2 );
const char32_t c3 = in.peek_byte( 3 );
if ( ( ( c1 & 0xC0 ) == 0x80 ) && ( ( c2 & 0xC0 ) == 0x80 ) && ( ( c3 & 0xC0 ) == 0x80 ) ) {
c0 &= 0x07;
c0 <<= 6;
c0 |= ( c1 & 0x3F );
c0 <<= 6;
c0 |= ( c2 & 0x3F );
c0 <<= 6;
c0 |= ( c3 & 0x3F );
if ( c0 >= 0x10000 && c0 <= 0x10FFFF ) {
return { c0, 4 };
}
}
}
}
return { 0, 0 };
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,91 @@
// Copyright (c) 2015-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_TAO_CPP_PEGTL_STRING_HH
#define TAO_CPP_PEGTL_INTERNAL_TAO_CPP_PEGTL_STRING_HH
#include <type_traits>
#include <cstddef>
#include "../ascii.hh"
namespace tao_json_pegtl
{
// Inspired by https://github.com/irrequietus/typestring
// Rewritten and reduced to what is needed for the PEGTL
// and to work with Visual Studio 2015.
namespace internal
{
template< typename, typename, typename, typename, typename, typename, typename, typename >
struct string_join;
template< template< char ... > class S, char ... C0s, char ... C1s, char ... C2s, char ... C3s, char ... C4s, char ... C5s, char ... C6s, char ... C7s >
struct string_join< S< C0s ... >, S< C1s ... >, S< C2s ... >, S< C3s ... >, S< C4s ... >, S< C5s ... >, S< C6s ... >, S< C7s ... > >
{
using type = S< C0s ..., C1s ..., C2s ..., C3s ..., C4s ..., C5s ..., C6s ..., C7s ... >;
};
template< template< char ... > class S, char, bool >
struct string_at
{
using type = S<>;
};
template< template< char ... > class S, char C >
struct string_at< S, C, true >
{
using type = S< C >;
};
template< typename T, std::size_t S >
struct string_max_length
{
static_assert( S <= 512, "String longer than 512 (excluding terminating \\0)!" );
using type = T;
};
} // namespace internal
} // namespace tao_json_pegtl
#define TAO_CPP_PEGTL_INTERNAL_EMPTY()
#define TAO_CPP_PEGTL_INTERNAL_DEFER( X ) X TAO_CPP_PEGTL_INTERNAL_EMPTY()
#define TAO_CPP_PEGTL_INTERNAL_EXPAND(...) __VA_ARGS__
#define TAO_CPP_PEGTL_INTERNAL_STRING_AT( S, x, n ) \
tao_json_pegtl::internal::string_at< S, ( 0##n < sizeof( x ) ) ? x[ 0##n ] : 0, ( 0##n < sizeof( x ) - 1 ) >::type
#define TAO_CPP_PEGTL_INTERNAL_JOIN_8( M, S, x, n ) \
tao_json_pegtl::internal::string_join< \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##0 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##1 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##2 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##3 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##4 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##5 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##6 ), \
TAO_CPP_PEGTL_INTERNAL_DEFER( M )( S, x, n##7 )>::type
#define TAO_CPP_PEGTL_INTERNAL_STRING_8( S, x, n ) \
TAO_CPP_PEGTL_INTERNAL_JOIN_8( TAO_CPP_PEGTL_INTERNAL_STRING_AT, S, x, n )
#define TAO_CPP_PEGTL_INTERNAL_STRING_64( S, x, n ) \
TAO_CPP_PEGTL_INTERNAL_JOIN_8( TAO_CPP_PEGTL_INTERNAL_STRING_8, S, x, n )
#define TAO_CPP_PEGTL_INTERNAL_STRING_512( S, x, n ) \
TAO_CPP_PEGTL_INTERNAL_JOIN_8( TAO_CPP_PEGTL_INTERNAL_STRING_64, S, x, n )
#define TAO_CPP_PEGTL_INTERNAL_STRING( S, x ) \
TAO_CPP_PEGTL_INTERNAL_EXPAND( \
TAO_CPP_PEGTL_INTERNAL_EXPAND( \
TAO_CPP_PEGTL_INTERNAL_EXPAND( \
tao_json_pegtl::internal::string_max_length< TAO_CPP_PEGTL_INTERNAL_STRING_512( S, x, ), sizeof( x ) - 1 >::type ) ) )
#define tao_json_pegtl_string_t( x ) \
TAO_CPP_PEGTL_INTERNAL_STRING( tao_json_pegtl::ascii::string, x )
#define tao_json_pegtl_istring_t( x ) \
TAO_CPP_PEGTL_INTERNAL_STRING( tao_json_pegtl::ascii::istring, x )
#endif

View File

@ -0,0 +1,46 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_PLUS_HH
#define TAO_CPP_PEGTL_INTERNAL_PLUS_HH
#include <type_traits>
#include "opt.hh"
#include "rule_match_three.hh"
#include "seq.hh"
#include "star.hh"
#include "skip_control.hh"
#include "../apply_mode.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
// While plus<> could easily be implemented with
// seq< Rule, Rules ..., star< Rule, Rules ... > > we
// provide an explicit implementation to optimize away
// the otherwise created input mark.
template< typename Rule, typename ... Rules >
struct plus
{
using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rule, Rules ..., opt< plus > >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
return rule_match_three< seq< Rule, Rules ... >, A, Action, Control >::match( in, st ... ) && rule_match_three< star< Rule, Rules ... >, A, Action, Control >::match( in, st ... );
}
};
template< typename Rule, typename ... Rules >
struct skip_control< plus< Rule, Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,39 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RAISE_HH
#define TAO_CPP_PEGTL_INTERNAL_RAISE_HH
#include <cstdlib>
#include <type_traits>
#include "skip_control.hh"
#include "../apply_mode.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename T >
struct raise
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
Control< T >::raise( const_cast< const Input & >( in ), st ... );
std::abort(); // LCOV_EXCL_LINE
}
};
template< typename T >
struct skip_control< raise< T > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,60 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RANGE_HH
#define TAO_CPP_PEGTL_INTERNAL_RANGE_HH
#include "any.hh"
#include "bump_util.hh"
#include "skip_control.hh"
#include "result_on_found.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi >
struct range
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< int Eol >
struct can_match_eol
{
static constexpr bool value = ( ( ( Lo <= Eol ) && ( Eol <= Hi ) ) == bool( R ) );
};
// suppress warning with GCC 4.7
template< typename T >
static inline bool dummy_less_or_equal( const T a, const T b )
{
return a <= b;
}
template< typename Input >
static bool match( Input & in )
{
using eol_t = typename Input::eol_t;
if ( ! in.empty() ) {
if ( const auto t = Peek::peek( in ) ) {
if ( ( dummy_less_or_equal( Lo, t.data ) && dummy_less_or_equal( t.data, Hi ) ) == bool( R ) ) {
bump_impl< can_match_eol< eol_t::ch >::value >::bump( in, t.size );
return true;
}
}
}
return false;
}
};
template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi >
struct skip_control< range< R, Peek, Lo, Hi > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,92 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RANGES_HH
#define TAO_CPP_PEGTL_INTERNAL_RANGES_HH
#include "any.hh"
#include "range.hh"
#include "bump_util.hh"
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< int Eol, typename Char, Char ... Cs > struct ranges_impl;
template< int Eol, typename Char >
struct ranges_impl< Eol, Char >
{
static constexpr bool can_match_eol = false;
static bool match( const Char )
{
return false;
}
};
template< int Eol, typename Char, Char Eq >
struct ranges_impl< Eol, Char, Eq >
{
static constexpr bool can_match_eol = ( Eq == Eol );
static bool match( const Char c )
{
return c == Eq;
}
};
template< int Eol, typename Char, Char Lo, Char Hi, Char ... Cs >
struct ranges_impl< Eol, Char, Lo, Hi, Cs ... >
{
static constexpr bool can_match_eol = ( ( ( Lo <= Eol ) && ( Eol <= Hi ) ) || ranges_impl< Eol, Char, Cs ... >::can_match_eol );
static bool match( const Char c )
{
return ( ( Lo <= c ) && ( c <= Hi ) ) || ranges_impl< Eol, Char, Cs ... >::match( c );
}
};
template< typename Peek, typename Peek::data_t ... Cs >
struct ranges
{
using analyze_t = analysis::generic< analysis::rule_type::ANY >;
template< int Eol >
struct can_match_eol
{
static constexpr bool value = ranges_impl< Eol, typename Peek::data_t, Cs ... >::can_match_eol;
};
template< typename Input >
static bool match( Input & in )
{
using eol_t = typename Input::eol_t;
if ( ! in.empty() ) {
if ( const auto t = Peek::peek( in ) ) {
if ( ranges_impl< eol_t::ch, typename Peek::data_t, Cs ... >::match( t.data ) ) {
bump_impl< can_match_eol< eol_t::ch >::value >::bump( in, t.size );
return true;
}
}
}
return false;
}
};
template< typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi >
struct ranges< Peek, Lo, Hi >
: range< result_on_found::SUCCESS, Peek, Lo, Hi > {};
template< typename Peek, typename Peek::data_t ... Cs >
struct skip_control< ranges< Peek, Cs ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,53 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_REP_HH
#define TAO_CPP_PEGTL_INTERNAL_REP_HH
#include "skip_control.hh"
#include "trivial.hh"
#include "rule_conjunction.hh"
#include "../analysis/counted.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Num, typename ... Rules > struct rep;
template< unsigned Num, typename ... Rules >
struct skip_control< rep< Num, Rules ... > > : std::true_type {};
template< unsigned Num >
struct rep< Num >
: trivial< true > {};
template< typename Rule, typename ... Rules >
struct rep< 0, Rule, Rules ... >
: trivial< true > {};
template< unsigned Num, typename ... Rules >
struct rep
{
using analyze_t = analysis::counted< analysis::rule_type::SEQ, Num, Rules ... >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
for ( unsigned i = 0; i != Num; ++i ) {
if ( ! rule_conjunction< Rules ... >::template match< A, Action, Control >( in, st ... ) ) {
return false;
}
}
return m( true );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,22 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_REP_MIN_HH
#define TAO_CPP_PEGTL_INTERNAL_REP_MIN_HH
#include "seq.hh"
#include "rep.hh"
#include "star.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Min, typename Rule, typename ... Rules >
using rep_min = seq< rep< Min, Rule, Rules ... >, star< Rule, Rules ... > >;
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,70 @@
// Copyright (c) 2014-2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_REP_MIN_MAX_HH
#define TAO_CPP_PEGTL_INTERNAL_REP_MIN_MAX_HH
#include <type_traits>
#include "skip_control.hh"
#include "trivial.hh"
#include "not_at.hh"
#include "rule_conjunction.hh"
#include "rule_match_three.hh"
#include "seq.hh"
#include "../apply_mode.hh"
#include "../analysis/counted.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Min, unsigned Max, typename ... Rules > struct rep_min_max;
template< unsigned Min, unsigned Max, typename ... Rules >
struct skip_control< rep_min_max< Min, Max, Rules ... > > : std::true_type {};
template< unsigned Min, unsigned Max >
struct rep_min_max< Min, Max >
: trivial< false >
{
static_assert( Min <= Max, "invalid rep_min_max rule (maximum number of repetitions smaller than minimum)" );
};
template< typename Rule, typename ... Rules >
struct rep_min_max< 0, 0, Rule, Rules ... >
: not_at< Rule, Rules ... >
{ };
template< unsigned Min, unsigned Max, typename ... Rules >
struct rep_min_max
{
using analyze_t = analysis::counted< analysis::rule_type::SEQ, Min, Rules ... >;
static_assert( Min <= Max, "invalid rep_min_max rule (maximum number of repetitions smaller than minimum)" );
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
auto m = in.mark();
for ( unsigned i = 0; i != Min; ++i ) {
if ( ! rule_conjunction< Rules ... >::template match< A, Action, Control >( in, st ... ) ) {
return false;
}
}
for ( unsigned i = Min; i != Max; ++i ) {
if ( ! rule_match_three< seq< Rules ... >, A, Action, Control >::match( in, st ... ) ) {
return m( true );
}
}
return m( rule_match_three< not_at< Rules ... >, A, Action, Control >::match( in, st ... ) );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_REP_OPT_HH
#define TAO_CPP_PEGTL_INTERNAL_REP_OPT_HH
#include "skip_control.hh"
#include "rule_match_three.hh"
#include "seq.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Max, typename ... Rules >
struct rep_opt
{
using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules ... >;
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
for ( unsigned i = 0; ( i != Max ) && rule_match_three< seq< Rules ... >, A, Action, Control >::match( in, st ... ); ++i ) {}
return true;
}
};
template< unsigned Max, typename ... Rules >
struct skip_control< rep_opt< Max, Rules ... > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,34 @@
// Copyright (c) 2016 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_REQUIRE_HH
#define TAO_CPP_PEGTL_INTERNAL_REQUIRE_HH
#include "skip_control.hh"
#include "../analysis/generic.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< unsigned Amount >
struct require
{
using analyze_t = analysis::generic< analysis::rule_type::OPT >;
template< typename Input >
static bool match( Input & in )
{
return in.size( Amount ) >= Amount;
}
};
template< unsigned Amount >
struct skip_control< require< Amount > > : std::true_type {};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,21 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RESULT_ON_FOUND_HH
#define TAO_CPP_PEGTL_INTERNAL_RESULT_ON_FOUND_HH
namespace tao_json_pegtl
{
namespace internal
{
enum class result_on_found : bool
{
SUCCESS = true,
FAILURE = false
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,34 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RULE_CONJUNCTION_HH
#define TAO_CPP_PEGTL_INTERNAL_RULE_CONJUNCTION_HH
#include "../apply_mode.hh"
namespace tao_json_pegtl
{
namespace internal
{
template< typename ... Rules >
struct rule_conjunction
{
template< apply_mode A, template< typename ... > class Action, template< typename ... > class Control, typename Input, typename ... States >
static bool match( Input & in, States && ... st )
{
#ifdef __cpp_fold_expressions
return ( Control< Rules >::template match< A, Action, Control >( in, st ... ) && ... );
#else
bool result = true;
using swallow = bool[];
(void)swallow{ result = result && Control< Rules >::template match< A, Action, Control >( in, st ... ) ..., true };
return result;
#endif
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,43 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RULE_MATCH_ONE_HH
#define TAO_CPP_PEGTL_INTERNAL_RULE_MATCH_ONE_HH
#include "../apply_mode.hh"
#include "skip_control.hh"
#include "rule_match_two.hh"
#include "rule_match_three.hh"
namespace tao_json_pegtl
{
namespace internal
{
// Forward to rule_match_two<> for all user-defined / -visible rules,
// but skip rule_match_two<> (which calls the control class' callbacks)
// and forward directly to rule_match_three<> when a rule is marked as
// an internal rule by skip_control<>.
template< typename Rule,
apply_mode A,
template< typename ... > class Action,
template< typename ... > class Control,
bool = skip_control< Rule >::value >
struct rule_match_one;
template< typename Rule, apply_mode A, template< typename ... > class Action, template< typename ... > class Control >
struct rule_match_one< Rule, A, Action, Control, false >
: rule_match_two< Rule, A, Action, Control >
{ };
template< typename Rule, apply_mode A, template< typename ... > class Action, template< typename ... > class Control >
struct rule_match_one< Rule, A, Action, Control, true >
: rule_match_three< Rule, A, Action, Control >
{ };
} // namespace internal
} // namespace tao_json_pegtl
#endif

View File

@ -0,0 +1,42 @@
// Copyright (c) 2014-2015 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/ColinH/PEGTL/
#ifndef TAO_CPP_PEGTL_INTERNAL_RULE_MATCH_THREE_HH
#define TAO_CPP_PEGTL_INTERNAL_RULE_MATCH_THREE_HH
#include "../apply_mode.hh"
namespace tao_json_pegtl
{
namespace internal
{
// The purpose of rule_match_three<> is to allow for two different
// signatures of a rule's match()-method. A more complicated but
// more general version which takes the explicit template parameters
// for A, Action and Control, and a more simple and limited version
// which takes the input as its only parameter. The latter is often
// sufficient and helps to keep the overhead smaller.
template< typename Rule, apply_mode A, template< typename ... > class Action, template< typename ... > class Control >
struct rule_match_three
{
template< typename Input, typename ... States >
static auto match( Input & in, States && ... st ) -> decltype( Rule::template match< A, Action, Control >( in, st ... ), true )
{
return Rule::template match< A, Action, Control >( in, st ... );
}
// NOTE: The additional "int = 0" is a work-around for missing expression SFINAE in VS2015.
template< typename Input, typename ... States, int = 0 >
static auto match( Input & in, States && ... ) -> decltype( Rule::match( in ), true )
{
return Rule::match( in );
}
};
} // namespace internal
} // namespace tao_json_pegtl
#endif

Some files were not shown because too many files have changed in this diff Show More