diff --git a/.gitignore b/.gitignore index 89399fb..fc598af 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,5 @@ qpmx.user.json # ts dummy dirs .ts-dummy +.qpmx-dev-cache +qpmx.json.user diff --git a/tools/3rdparty/3rdparty.pri b/tools/3rdparty/3rdparty.pri new file mode 100644 index 0000000..c0a9f8d --- /dev/null +++ b/tools/3rdparty/3rdparty.pri @@ -0,0 +1,5 @@ +HEADERS += \ + $$PWD/optional-lite/optional.hpp \ + $$PWD/variant-lite/variant.hpp + +INCLUDEPATH += $$PWD/optional-lite $$PWD/variant-lite diff --git a/tools/3rdparty/optional-lite/LICENSE.txt b/tools/3rdparty/optional-lite/LICENSE.txt new file mode 100644 index 0000000..127a5bc --- /dev/null +++ b/tools/3rdparty/optional-lite/LICENSE.txt @@ -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. \ No newline at end of file diff --git a/tools/3rdparty/optional-lite/optional.hpp b/tools/3rdparty/optional-lite/optional.hpp new file mode 100644 index 0000000..caac94c --- /dev/null +++ b/tools/3rdparty/optional-lite/optional.hpp @@ -0,0 +1,1214 @@ +// +// Copyright (c) 2014-2018 Martin Moene +// +// https://github.com/martinmoene/optional-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#ifndef NONSTD_OPTIONAL_LITE_HPP +#define NONSTD_OPTIONAL_LITE_HPP + +#define optional_lite_VERSION "3.0.0" + +// Compiler detection (C++20 is speculative): +// Note: MSVC supports C++14 since it supports C++17. + +#ifdef _MSVC_LANG +# define optional_MSVC_LANG _MSVC_LANG +#else +# define optional_MSVC_LANG 0 +#endif + +#define optional_CPP11 (__cplusplus == 201103L ) +#define optional_CPP11_OR_GREATER (__cplusplus >= 201103L || optional_MSVC_LANG >= 201103L ) +#define optional_CPP14_OR_GREATER (__cplusplus >= 201402L || optional_MSVC_LANG >= 201703L ) +#define optional_CPP17_OR_GREATER (__cplusplus >= 201703L || optional_MSVC_LANG >= 201703L ) +#define optional_CPP20_OR_GREATER (__cplusplus >= 202000L || optional_MSVC_LANG >= 202000L ) + +// use C++17 std::optional if available: + +#if defined( __has_include ) +# define optional_HAS_INCLUDE( arg ) __has_include( arg ) +#else +# define optional_HAS_INCLUDE( arg ) 0 +#endif + +#define optional_HAVE_STD_OPTIONAL ( optional_CPP17_OR_GREATER && optional_HAS_INCLUDE( ) ) + +#if optional_HAVE_STD_OPTIONAL + +#include + +namespace nonstd { + + using std::optional; + using std::bad_optional_access; + using std::hash; + + using std::nullopt; + using std::nullopt_t; + using std::in_place; + using std::in_place_type; + using std::in_place_index; + using std::in_place_t; + using std::in_place_type_t; + using std::in_place_index_t; + + using std::operator==; + using std::operator!=; + using std::operator<; + using std::operator<=; + using std::operator>; + using std::operator>=; + using std::make_optional; + using std::swap; +} + +#else // C++17 std::optional + +#include +#include +#include + +// optional-lite alignment configuration: + +#ifndef optional_CONFIG_MAX_ALIGN_HACK +# define optional_CONFIG_MAX_ALIGN_HACK 0 +#endif + +#ifndef optional_CONFIG_ALIGN_AS +// no default, used in #if defined() +#endif + +#ifndef optional_CONFIG_ALIGN_AS_FALLBACK +# define optional_CONFIG_ALIGN_AS_FALLBACK double +#endif + +// Compiler warning suppression: + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wundef" +#elif defined __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wundef" +#endif + +// half-open range [lo..hi): +#define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi ) + +#if defined(_MSC_VER) && !defined(__clang__) +# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) ) +#else +# define optional_COMPILER_MSVC_VERSION 0 +#endif + +#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch ) + +#if defined __GNUC__ +# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#else +# define optional_COMPILER_GNUC_VERSION 0 +#endif + +#if defined __clang__ +# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#else +# define optional_COMPILER_CLANG_VERSION 0 +#endif + +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 ) +# pragma warning( push ) +# pragma warning( disable: 4345 ) // initialization behavior changed +#endif + +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 ) +# pragma warning( push ) +# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' +#endif + +// Presence of language and library features: + +#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE ) + +// Presence of C++11 language features: + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 100 +# define optional_HAVE_AUTO 1 +# define optional_HAVE_NULLPTR 1 +# define optional_HAVE_STATIC_ASSERT 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 +# define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1 +# define optional_HAVE_INITIALIZER_LIST 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 +# define optional_HAVE_ALIAS_TEMPLATE 1 +# define optional_HAVE_CONSTEXPR_11 1 +# define optional_HAVE_ENUM_CLASS 1 +# define optional_HAVE_EXPLICIT_CONVERSION 1 +# define optional_HAVE_IS_DEFAULT 1 +# define optional_HAVE_IS_DELETE 1 +# define optional_HAVE_NOEXCEPT 1 +# define optional_HAVE_REF_QUALIFIER 1 +#endif + +// Presence of C++14 language features: + +#if optional_CPP14_OR_GREATER +# define optional_HAVE_CONSTEXPR_14 1 +#endif + +// Presence of C++17 language features: + +#if optional_CPP17_OR_GREATER +# define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1 +#endif + +// Presence of C++ library features: + +#if optional_COMPILER_GNUC_VERSION +# define optional_HAVE_TR1_TYPE_TRAITS 1 +# define optional_HAVE_TR1_ADD_POINTER 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 90 +# define optional_HAVE_TYPE_TRAITS 1 +# define optional_HAVE_STD_ADD_POINTER 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 110 +# define optional_HAVE_ARRAY 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 +# define optional_HAVE_CONDITIONAL 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 || (optional_COMPILER_MSVC_VERSION >= 90 && _HAS_CPP0X) +# define optional_HAVE_CONTAINER_DATA_METHOD 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 +# define optional_HAVE_REMOVE_CV 1 +#endif + +#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 +# define optional_HAVE_SIZED_TYPES 1 +#endif + +// For the rest, consider VC14 as C++11 for optional-lite: + +#if optional_COMPILER_MSVC_VERSION >= 140 +# undef optional_CPP11_OR_GREATER +# define optional_CPP11_OR_GREATER 1 +#endif + +// C++ feature usage: + +#if optional_HAVE( CONSTEXPR_11 ) +# define optional_constexpr constexpr +#else +# define optional_constexpr /*constexpr*/ +#endif + +#if optional_HAVE( CONSTEXPR_14 ) +# define optional_constexpr14 constexpr +#else +# define optional_constexpr14 /*constexpr*/ +#endif + +#if optional_HAVE( NOEXCEPT ) +# define optional_noexcept noexcept +#else +# define optional_noexcept /*noexcept*/ +#endif + +#if optional_HAVE( NULLPTR ) +# define optional_nullptr nullptr +#else +# define optional_nullptr NULL +#endif + +#if optional_HAVE( REF_QUALIFIER ) +# define optional_ref_qual & +# define optional_refref_qual && +#else +# define optional_ref_qual /*&*/ +# define optional_refref_qual /*&&*/ +#endif + +// additional includes: + +#if optional_CPP11_OR_GREATER +# include +#endif + +#if optional_HAVE( INITIALIZER_LIST ) +# include +#endif + +#if optional_HAVE( TYPE_TRAITS ) +# include +#elif optional_HAVE( TR1_TYPE_TRAITS ) +# include +#endif + +// type traits needed: + +namespace nonstd { namespace optional_lite { namespace detail { + +#if optional_HAVE( CONDITIONAL ) + using std::conditional; +#else + template< bool B, typename T, typename F > struct conditional { typedef T type; }; + template< typename T, typename F > struct conditional { typedef F type; }; +#endif // optional_HAVE_CONDITIONAL + +}}} + +// +// in_place: code duplicated in any-lite, optional-lite, variant-lite: +// + +#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES + +namespace nonstd { + +namespace detail { + +template< class T > +struct in_place_type_tag {}; + +template< std::size_t I > +struct in_place_index_tag {}; + +} // namespace detail + +struct in_place_t {}; + +template< class T > +inline in_place_t in_place( detail::in_place_type_tag = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t I > +inline in_place_t in_place( detail::in_place_index_tag = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +template< class T > +inline in_place_t in_place_type( detail::in_place_type_tag = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t I > +inline in_place_t in_place_index( detail::in_place_index_tag = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +// mimic templated typedef: + +#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) + +#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 + +} // namespace nonstd + +#endif // nonstd_lite_HAVE_IN_PLACE_TYPES + +// +// optional: +// + +namespace nonstd { namespace optional_lite { + +/// class optional + +template< typename T > +class optional; + +namespace detail { + +// C++11 emulation: + +struct nulltype{}; + +template< typename Head, typename Tail > +struct typelist +{ + typedef Head head; + typedef Tail tail; +}; + +#if optional_CONFIG_MAX_ALIGN_HACK + +// Max align, use most restricted type for alignment: + +#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) +#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) +#define optional_UNIQUE3( name, line ) name ## line + +#define optional_ALIGN_TYPE( type ) \ + type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) + +template< typename T > +struct struct_t { T _; }; + +union max_align_t +{ + optional_ALIGN_TYPE( char ); + optional_ALIGN_TYPE( short int ); + optional_ALIGN_TYPE( int ); + optional_ALIGN_TYPE( long int ); + optional_ALIGN_TYPE( float ); + optional_ALIGN_TYPE( double ); + optional_ALIGN_TYPE( long double ); + optional_ALIGN_TYPE( char * ); + optional_ALIGN_TYPE( short int * ); + optional_ALIGN_TYPE( int * ); + optional_ALIGN_TYPE( long int * ); + optional_ALIGN_TYPE( float * ); + optional_ALIGN_TYPE( double * ); + optional_ALIGN_TYPE( long double * ); + optional_ALIGN_TYPE( void * ); + +#ifdef HAVE_LONG_LONG + optional_ALIGN_TYPE( long long ); +#endif + + struct Unknown; + + Unknown ( * optional_UNIQUE(_) )( Unknown ); + Unknown * Unknown::* optional_UNIQUE(_); + Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); + + struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_); + struct_t< Unknown * Unknown::* > optional_UNIQUE(_); + struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); +}; + +#undef optional_UNIQUE +#undef optional_UNIQUE2 +#undef optional_UNIQUE3 + +#undef optional_ALIGN_TYPE + +#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK + +// Use user-specified type for alignment: + +#define optional_ALIGN_AS( unused ) \ + optional_CONFIG_ALIGN_AS + +#else // optional_CONFIG_MAX_ALIGN_HACK + +// Determine POD type to use for alignment: + +#define optional_ALIGN_AS( to_align ) \ + typename type_of_size< alignment_types, alignment_of< to_align >::value >::type + +template +struct alignment_of; + +template +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; + +template +struct alignment_logic +{ + enum { value = A < S ? A : S }; +}; + +template< typename T > +struct alignment_of +{ + enum { value = alignment_logic< + sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value, }; +}; + +template< typename List, size_t N > +struct type_of_size +{ + typedef typename conditional< + N == sizeof( typename List::head ), + typename List::head, + typename type_of_size::type >::type type; +}; + +template< size_t N > +struct type_of_size< nulltype, N > +{ + typedef optional_CONFIG_ALIGN_AS_FALLBACK type; +}; + +template< typename T> +struct struct_t { T _; }; + +#define optional_ALIGN_TYPE( type ) \ + typelist< type , typelist< struct_t< type > + +struct Unknown; + +typedef + optional_ALIGN_TYPE( char ), + optional_ALIGN_TYPE( short ), + optional_ALIGN_TYPE( int ), + optional_ALIGN_TYPE( long ), + optional_ALIGN_TYPE( float ), + optional_ALIGN_TYPE( double ), + optional_ALIGN_TYPE( long double ), + + optional_ALIGN_TYPE( char *), + optional_ALIGN_TYPE( short * ), + optional_ALIGN_TYPE( int * ), + optional_ALIGN_TYPE( long * ), + optional_ALIGN_TYPE( float * ), + optional_ALIGN_TYPE( double * ), + optional_ALIGN_TYPE( long double * ), + + optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), + optional_ALIGN_TYPE( Unknown * Unknown::* ), + optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), + + nulltype + > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + > > > > > > + alignment_types; + +#undef optional_ALIGN_TYPE + +#endif // optional_CONFIG_MAX_ALIGN_HACK + +/// C++03 constructed union to hold value. + +template< typename T > +union storage_t +{ +private: + friend class optional; + + typedef T value_type; + + storage_t() {} + + storage_t( value_type const & v ) + { + construct_value( v ); + } + + void construct_value( value_type const & v ) + { + ::new( value_ptr() ) value_type( v ); + } + +#if optional_CPP11_OR_GREATER + + storage_t( value_type && v ) + { + construct_value( std::move( v ) ); + } + + void construct_value( value_type && v ) + { + ::new( value_ptr() ) value_type( std::move( v ) ); + } + + template< class... Args > + void emplace( Args&&... args ) + { + ::new( value_ptr() ) value_type( std::forward(args)... ); + } + + template< class U, class... Args > + void emplace( std::initializer_list il, Args&&... args ) + { + ::new( value_ptr() ) value_type( il, std::forward(args)... ); + } + +#endif + + void destruct_value() + { + value_ptr()->~T(); + } + + value_type const * value_ptr() const + { + return as(); + } + + value_type * value_ptr() + { + return as(); + } + + value_type const & value() const optional_ref_qual + { + return * value_ptr(); + } + + value_type & value() optional_ref_qual + { + return * value_ptr(); + } + +#if optional_CPP11_OR_GREATER + + value_type const && value() const optional_refref_qual + { + return * value_ptr(); + } + + value_type && value() optional_refref_qual + { + return * value_ptr(); + } + +#endif + +#if optional_CPP11_OR_GREATER + + using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; + aligned_storage_t data; + +#elif optional_CONFIG_MAX_ALIGN_HACK + + typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; + + max_align_t hack; + aligned_storage_t data; + +#else + typedef optional_ALIGN_AS(value_type) align_as_type; + + typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; + aligned_storage_t data; + +# undef optional_ALIGN_AS + +#endif // optional_CONFIG_MAX_ALIGN_HACK + + void * ptr() optional_noexcept + { + return &data; + } + + void const * ptr() const optional_noexcept + { + return &data; + } + + template + U * as() + { + return reinterpret_cast( ptr() ); + } + + template + U const * as() const + { + return reinterpret_cast( ptr() ); + } +}; + +} // namespace detail + +/// disengaged state tag + +struct nullopt_t +{ + struct init{}; + optional_constexpr nullopt_t( init ) {} +}; + +#if optional_HAVE( CONSTEXPR_11 ) +constexpr nullopt_t nullopt{ nullopt_t::init{} }; +#else +// extra parenthesis to prevent the most vexing parse: +const nullopt_t nullopt(( nullopt_t::init() )); +#endif + +/// optional access error + +class bad_optional_access : public std::logic_error +{ +public: + explicit bad_optional_access() + : logic_error( "bad optional access" ) {} +}; + +/// optional + +template< typename T> +class optional +{ +private: + typedef void (optional::*safe_bool)() const; + +public: + typedef T value_type; + + optional_constexpr optional() optional_noexcept + : has_value_( false ) + , contained() + {} + + optional_constexpr optional( nullopt_t ) optional_noexcept + : has_value_( false ) + , contained() + {} + + optional( optional const & rhs ) + : has_value_( rhs.has_value() ) + { + if ( rhs.has_value() ) + contained.construct_value( rhs.contained.value() ); + } + +#if optional_CPP11_OR_GREATER + optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible::value ) + : has_value_( rhs.has_value() ) + { + if ( rhs.has_value() ) + contained.construct_value( std::move( rhs.contained.value() ) ); + } +#endif + + optional_constexpr optional( value_type const & value ) + : has_value_( true ) + , contained( value ) + {} + +#if optional_CPP11_OR_GREATER + + optional_constexpr optional( value_type && value ) + : has_value_( true ) + , contained( std::move( value ) ) + {} + + template< class... Args > + optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args ) + : has_value_( true ) + , contained( T( std::forward(args)...) ) + {} + + template< class U, class... Args > + optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list il, Args&&... args ) + : has_value_( true ) + , contained( T( il, std::forward(args)...) ) + {} + +#endif // optional_CPP11_OR_GREATER + + ~optional() + { + if ( has_value() ) + contained.destruct_value(); + } + + // assignment + + optional & operator=( nullopt_t ) optional_noexcept + { + reset(); + return *this; + } + + optional & operator=( optional const & rhs ) +#if optional_CPP11_OR_GREATER + noexcept( std::is_nothrow_move_assignable::value && std::is_nothrow_move_constructible::value ) +#endif + { + if ( has_value() == true && rhs.has_value() == false ) reset(); + else if ( has_value() == false && rhs.has_value() == true ) initialize( *rhs ); + else if ( has_value() == true && rhs.has_value() == true ) contained.value() = *rhs; + return *this; + } + +#if optional_CPP11_OR_GREATER + + optional & operator=( optional && rhs ) noexcept + { + if ( has_value() == true && rhs.has_value() == false ) reset(); + else if ( has_value() == false && rhs.has_value() == true ) initialize( std::move( *rhs ) ); + else if ( has_value() == true && rhs.has_value() == true ) contained.value() = std::move( *rhs ); + return *this; + } + + template< class U, + typename = typename std::enable_if< std::is_same< typename std::decay::type, T>::value >::type > + optional & operator=( U && v ) + { + if ( has_value() ) contained.value() = std::forward( v ); + else initialize( T( std::forward( v ) ) ); + return *this; + } + + template< class... Args > + void emplace( Args&&... args ) + { + *this = nullopt; + contained.emplace( std::forward(args)... ); + has_value_ = true; + } + + + template< class U, class... Args > + void emplace( std::initializer_list il, Args&&... args ) + { + *this = nullopt; + contained.emplace( il, std::forward(args)... ); + has_value_ = true; + } + +#endif // optional_CPP11_OR_GREATER + + // swap + + void swap( optional & rhs ) +#if optional_CPP11_OR_GREATER + noexcept( std::is_nothrow_move_constructible::value && noexcept( std::swap( std::declval(), std::declval() ) ) ) +#endif + { + using std::swap; + if ( has_value() == true && rhs.has_value() == true ) { swap( **this, *rhs ); } + else if ( has_value() == false && rhs.has_value() == true ) { initialize( *rhs ); rhs.reset(); } + else if ( has_value() == true && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); } + } + + // observers + + optional_constexpr value_type const * operator ->() const + { + return assert( has_value() ), + contained.value_ptr(); + } + + optional_constexpr14 value_type * operator ->() + { + return assert( has_value() ), + contained.value_ptr(); + } + + optional_constexpr value_type const & operator *() const optional_ref_qual + { + return assert( has_value() ), + contained.value(); + } + + optional_constexpr14 value_type & operator *() optional_ref_qual + { + return assert( has_value() ), + contained.value(); + } + +#if optional_CPP11_OR_GREATER + + optional_constexpr value_type const && operator *() const optional_refref_qual + { + return assert( has_value() ), + std::move( contained.value() ); + } + + optional_constexpr14 value_type && operator *() optional_refref_qual + { + return assert( has_value() ), + std::move( contained.value() ); + } + +#endif + +#if optional_CPP11_OR_GREATER + optional_constexpr explicit operator bool() const optional_noexcept + { + return has_value(); + } +#else + optional_constexpr operator safe_bool() const optional_noexcept + { + return has_value() ? &optional::this_type_does_not_support_comparisons : 0; + } +#endif + + optional_constexpr bool has_value() const optional_noexcept + { + return has_value_; + } + + optional_constexpr14 value_type const & value() const optional_ref_qual + { + if ( ! has_value() ) + throw bad_optional_access(); + + return contained.value(); + } + + optional_constexpr14 value_type & value() optional_ref_qual + { + if ( ! has_value() ) + throw bad_optional_access(); + + return contained.value(); + } + +#if optional_HAVE( REF_QUALIFIER ) + + optional_constexpr14 value_type const && value() const optional_refref_qual + { + if ( ! has_value() ) + throw bad_optional_access(); + + return std::move( contained.value() ); + } + + optional_constexpr14 value_type && value() optional_refref_qual + { + if ( ! has_value() ) + throw bad_optional_access(); + + return std::move( contained.value() ); + } + +#endif + +#if optional_CPP11_OR_GREATER + + template< class U > + optional_constexpr value_type value_or( U && v ) const optional_ref_qual + { + return has_value() ? contained.value() : static_cast(std::forward( v ) ); + } + + template< class U > + optional_constexpr value_type value_or( U && v ) const optional_refref_qual + { + return has_value() ? std::move( contained.value() ) : static_cast(std::forward( v ) ); + } + +#else + + template< class U > + optional_constexpr value_type value_or( U const & v ) const + { + return has_value() ? contained.value() : static_cast( v ); + } + +#endif // optional_CPP11_OR_GREATER + + // modifiers + + void reset() optional_noexcept + { + if ( has_value() ) + contained.destruct_value(); + + has_value_ = false; + } + +private: + void this_type_does_not_support_comparisons() const {} + + template< typename V > + void initialize( V const & value ) + { + assert( ! has_value() ); + contained.construct_value( value ); + has_value_ = true; + } + +#if optional_CPP11_OR_GREATER + template< typename V > + void initialize( V && value ) + { + assert( ! has_value() ); + contained.construct_value( std::move( value ) ); + has_value_ = true; + } + +#endif + +private: + bool has_value_; + detail::storage_t< value_type > contained; + +}; + +// Relational operators + +template< typename T, typename U > +inline optional_constexpr bool operator==( optional const & x, optional const & y ) +{ + return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( optional const & x, optional const & y ) +{ + return !(x == y); +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( optional const & x, optional const & y ) +{ + return (!y) ? false : (!x) ? true : *x < *y; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( optional const & x, optional const & y ) +{ + return (y < x); +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( optional const & x, optional const & y ) +{ + return !(y < x); +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( optional const & x, optional const & y ) +{ + return !(x < y); +} + +// Comparison with nullopt + +template< typename T > +inline optional_constexpr bool operator==( optional const & x, nullopt_t ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator==( nullopt_t, optional const & x ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator!=( optional const & x, nullopt_t ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator!=( nullopt_t, optional const & x ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator<( optional const &, nullopt_t ) optional_noexcept +{ + return false; +} + +template< typename T > +inline optional_constexpr bool operator<( nullopt_t, optional const & x ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator<=( optional const & x, nullopt_t ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator<=( nullopt_t, optional const & ) optional_noexcept +{ + return true; +} + +template< typename T > +inline optional_constexpr bool operator>( optional const & x, nullopt_t ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator>( nullopt_t, optional const & ) optional_noexcept +{ + return false; +} + +template< typename T > +inline optional_constexpr bool operator>=( optional const &, nullopt_t ) optional_noexcept +{ + return true; +} + +template< typename T > +inline optional_constexpr bool operator>=( nullopt_t, optional const & x ) optional_noexcept +{ + return (!x); +} + +// Comparison with T + +template< typename T, typename U > +inline optional_constexpr bool operator==( optional const & x, U const & v ) +{ + return bool(x) ? *x == v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator==( U const & v, optional const & x ) +{ + return bool(x) ? v == *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( optional const & x, U const & v ) +{ + return bool(x) ? *x != v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( U const & v, optional const & x ) +{ + return bool(x) ? v != *x : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( optional const & x, U const & v ) +{ + return bool(x) ? *x < v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( U const & v, optional const & x ) +{ + return bool(x) ? v < *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( optional const & x, U const & v ) +{ + return bool(x) ? *x <= v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( U const & v, optional const & x ) +{ + return bool(x) ? v <= *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( optional const & x, U const & v ) +{ + return bool(x) ? *x > v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( U const & v, optional const & x ) +{ + return bool(x) ? v > *x : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( optional const & x, U const & v ) +{ + return bool(x) ? *x >= v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( U const & v, optional const & x ) +{ + return bool(x) ? v >= *x : true; +} + +// Specialized algorithms + +template< typename T > +void swap( optional & x, optional & y ) +#if optional_CPP11_OR_GREATER + noexcept( noexcept( x.swap(y) ) ) +#endif +{ + x.swap( y ); +} + +#if optional_CPP11_OR_GREATER + +template< class T > +optional_constexpr optional< typename std::decay::type > make_optional( T && v ) +{ + return optional< typename std::decay::type >( std::forward( v ) ); +} + +template< class T, class...Args > +optional_constexpr optional make_optional( Args&&... args ) +{ + return optional( in_place, std::forward(args)...); +} + +template< class T, class U, class... Args > +optional_constexpr optional make_optional( std::initializer_list il, Args&&... args ) +{ + return optional( in_place, il, std::forward(args)...); +} + +#else + +template< typename T > +optional make_optional( T const & v ) +{ + return optional( v ); +} + +#endif // optional_CPP11_OR_GREATER + +} // namespace optional + +using namespace optional_lite; + +} // namespace nonstd + +#if optional_CPP11_OR_GREATER + +// specialize the std::hash algorithm: + +namespace std { + +template< class T > +struct hash< nonstd::optional > +{ +public: + std::size_t operator()( nonstd::optional const & v ) const optional_noexcept + { + return bool( v ) ? hash()( *v ) : 0; + } +}; + +} //namespace std + +#endif // optional_CPP11_OR_GREATER + +#ifdef __clang__ +# pragma clang diagnostic pop +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +#endif // have C++17 std::optional + +#endif // NONSTD_OPTIONAL_LITE_HPP \ No newline at end of file diff --git a/tools/3rdparty/variant-lite/LICENSE.txt b/tools/3rdparty/variant-lite/LICENSE.txt new file mode 100644 index 0000000..127a5bc --- /dev/null +++ b/tools/3rdparty/variant-lite/LICENSE.txt @@ -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. \ No newline at end of file diff --git a/tools/3rdparty/variant-lite/variant.hpp b/tools/3rdparty/variant-lite/variant.hpp new file mode 100644 index 0000000..6c888dc --- /dev/null +++ b/tools/3rdparty/variant-lite/variant.hpp @@ -0,0 +1,1533 @@ +// Copyright 2016-2018 by Martin Moene +// +// https://github.com/martinmoene/variant-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#ifndef NONSTD_VARIANT_LITE_HPP +#define NONSTD_VARIANT_LITE_HPP + +#define variant_lite_VERSION "1.0.0" + +// variant-lite configuration: + +#ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO +# define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0 +#endif + +#ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO +# define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0 +#endif + +// Compiler detection: + +#ifdef _MSVC_LANG +# define variant_MSVC_LANG _MSVC_LANG +#else +# define variant_MSVC_LANG 0 +#endif + +#define variant_CPP11_OR_GREATER ( __cplusplus >= 201103L || variant_MSVC_LANG >= 201103L ) +#define variant_CPP14_OR_GREATER ( __cplusplus >= 201402L || variant_MSVC_LANG >= 201703L ) +#define variant_CPP17_OR_GREATER ( __cplusplus >= 201703L || variant_MSVC_LANG >= 201703L ) + +// use C++17 std::variant if available: + +#if defined( __has_include ) +# define variant_HAS_INCLUDE( arg ) __has_include( arg ) +#else +# define variant_HAS_INCLUDE( arg ) 0 +#endif + +#if variant_HAS_INCLUDE( ) && variant_CPP17_OR_GREATER + +#define variant_HAVE_STD_VARIANT 1 + +#include + +#if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO +# define variant_size_V(T) nonstd::variant_size::value +#endif + +#if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO +# define variant_alternative_T(I,T) typename nonstd::variant_alternative::type +#endif + +namespace nonstd { + + using std::variant; + using std::monostate; + using std::bad_variant_access; + using std::variant_size; + using std::variant_size_v; + using std::variant_alternative; + using std::variant_alternative_t; + using std::hash; + + using std::in_place; + using std::in_place_type; + using std::in_place_index; + using std::in_place_t; + using std::in_place_type_t; + using std::in_place_index_t; + + using std::visit; + using std::holds_alternative; + using std::get; + using std::get_if; + using std::operator==; + using std::operator!=; + using std::operator<; + using std::operator<=; + using std::operator>; + using std::operator>=; + using std::swap; + + constexpr auto variant_npos = std::variant_npos; + +} + +#else // C++17 std::variant + +#include +#include +#include +#include +#include + +// variant-lite alignment configuration: + +#ifndef variant_CONFIG_MAX_ALIGN_HACK +# define variant_CONFIG_MAX_ALIGN_HACK 0 +#endif + +#ifndef variant_CONFIG_ALIGN_AS +// no default, used in #if defined() +#endif + +#ifndef variant_CONFIG_ALIGN_AS_FALLBACK +# define variant_CONFIG_ALIGN_AS_FALLBACK double +#endif + +// half-open range [lo..hi): +#define variant_BETWEEN( v, lo, hi ) ( lo <= v && v < hi ) + +#if defined(_MSC_VER) && !defined(__clang__) +# define variant_COMPILER_MSVC_VERSION (_MSC_VER / 100 - 5 - (_MSC_VER < 1900)) +#else +# define variant_COMPILER_MSVC_VERSION 0 +#endif + +#if defined __GNUC__ +# define variant_COMPILER_GNUC_VERSION __GNUC__ +#else +# define variant_COMPILER_GNUC_VERSION 0 +#endif + +#if variant_BETWEEN(variant_COMPILER_MSVC_VERSION, 7, 14 ) +# pragma warning( push ) +# pragma warning( disable: 4345 ) // initialization behavior changed +#endif + +// Presence of C++11 language features: + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 10 +# define variant_HAVE_AUTO 1 +# define variant_HAVE_NULLPTR 1 +# define variant_HAVE_STATIC_ASSERT 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 12 +# define variant_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1 +# define variant_HAVE_INITIALIZER_LIST 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 14 +# define variant_HAVE_ALIAS_TEMPLATE 1 +# define variant_HAVE_CONSTEXPR_11 1 +# define variant_HAVE_ENUM_CLASS 1 +# define variant_HAVE_EXPLICIT_CONVERSION 1 +# define variant_HAVE_IS_DEFAULT 1 +# define variant_HAVE_IS_DELETE 1 +# define variant_HAVE_NOEXCEPT 1 +# define variant_HAVE_OVERRIDE 1 +#endif + +// Presence of C++14 language features: + +#if variant_CPP14_OR_GREATER +# define variant_HAVE_CONSTEXPR_14 1 +#endif + +// Presence of C++17 language features: + +#if variant_CPP17_OR_GREATER +# define variant_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1 +#endif + +// Presence of C++ library features: + +#if variant_COMPILER_GNUC_VERSION +# define variant_HAVE_TR1_TYPE_TRAITS 1 +# define variant_HAVE_TR1_ADD_POINTER 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 9 +# define variant_HAVE_TYPE_TRAITS 1 +# define variant_HAVE_STD_ADD_POINTER 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 11 +# define variant_HAVE_ARRAY 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 12 +# define variant_HAVE_CONDITIONAL 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 14 || (variant_COMPILER_MSVC_VERSION >= 9 && _HAS_CPP0X) +# define variant_HAVE_CONTAINER_DATA_METHOD 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 12 +# define variant_HAVE_REMOVE_CV 1 +#endif + +#if variant_CPP11_OR_GREATER || variant_COMPILER_MSVC_VERSION >= 14 +# define variant_HAVE_SIZED_TYPES 1 +#endif + +// For the rest, consider VC14 as C++11 for variant-lite: + +#if variant_COMPILER_MSVC_VERSION >= 14 +# undef variant_CPP11_OR_GREATER +# define variant_CPP11_OR_GREATER 1 +#endif + +// C++ feature usage: + +#if variant_HAVE_CONSTEXPR_11 +# define variant_constexpr constexpr +#else +# define variant_constexpr /*constexpr*/ +#endif + +#if variant_HAVE_CONSTEXPR_14 +# define variant_constexpr14 constexpr +#else +# define variant_constexpr14 /*constexpr*/ +#endif + +#if variant_HAVE_NOEXCEPT +# define variant_noexcept noexcept +#else +# define variant_noexcept /*noexcept*/ +#endif + +#if variant_HAVE_NULLPTR +# define variant_nullptr nullptr +#else +# define variant_nullptr NULL +#endif + +#if variant_HAVE_OVERRIDE +# define variant_override override +#else +# define variant_override /*override*/ +#endif + +// additional includes: + +#if variant_HAVE_INITIALIZER_LIST +# include +#endif + +#if variant_HAVE_TYPE_TRAITS +# include +#elif variant_HAVE_TR1_TYPE_TRAITS +# include +#endif + +// +// in_place: code duplicated in any-lite, optional-lite, variant-lite: +// + +#if ! nonstd_lite_HAVE_IN_PLACE_TYPES + +namespace nonstd { + +namespace detail { + +template< class T > +struct in_place_type_tag {}; + +template< std::size_t I > +struct in_place_index_tag {}; + +} // namespace detail + +struct in_place_t {}; + +template< class T > +inline in_place_t in_place( detail::in_place_type_tag = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t I > +inline in_place_t in_place( detail::in_place_index_tag = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +template< class T > +inline in_place_t in_place_type( detail::in_place_type_tag = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t I > +inline in_place_t in_place_index( detail::in_place_index_tag = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +// mimic templated typedef: + +#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) + +#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 + +} // namespace nonstd + +#endif // nonstd_lite_HAVE_IN_PLACE_TYPES + +// +// variant: +// + +namespace nonstd { namespace variants { + +namespace detail { + +// C++11 emulation: + +#if variant_HAVE_STD_ADD_POINTER + +using std::add_pointer; + +#elif variant_HAVE_TR1_ADD_POINTER + +using std::tr1::add_pointer; + +#else + +template< class T > struct remove_reference { typedef T type; }; +template< class T > struct remove_reference { typedef T type; }; + +template< class T > struct add_pointer +{ + typedef typename remove_reference::type * type; +}; + +#endif // variant_HAVE_STD_ADD_POINTER + +#if variant_HAVE_REMOVE_CV + +using std::remove_cv; + +#else + +template< class T > struct remove_const { typedef T type; }; +template< class T > struct remove_const { typedef T type; }; + +template< class T > struct remove_volatile { typedef T type; }; +template< class T > struct remove_volatile { typedef T type; }; + +template< class T > +struct remove_cv +{ + typedef typename remove_volatile::type>::type type; +}; + +#endif // variant_HAVE_REMOVE_CV + +#if variant_HAVE_CONDITIONAL + +using std::conditional; + +#else + +template< bool Cond, class Then, class Else > +struct conditional; + +template< class Then, class Else > +struct conditional< true , Then, Else > { typedef Then type; }; + +template< class Then, class Else > +struct conditional< false, Then, Else > { typedef Else type; }; + +#endif // variant_HAVE_CONDITIONAL + +// typelist: + +#define variant_TL1( T1 ) detail::typelist< T1, detail::nulltype > +#define variant_TL2( T1, T2 ) detail::typelist< T1, variant_TL1( T2) > +#define variant_TL3( T1, T2, T3 ) detail::typelist< T1, variant_TL2( T2, T3 ) > +#define variant_TL4( T1, T2, T3, T4 ) detail::typelist< T1, variant_TL3( T2, T3, T4 ) > +#define variant_TL5( T1, T2, T3, T4, T5 ) detail::typelist< T1, variant_TL4( T2, T3, T4, T5 ) > +#define variant_TL6( T1, T2, T3, T4, T5, T6 ) detail::typelist< T1, variant_TL5( T2, T3, T4, T5, T6 ) > +#define variant_TL7( T1, T2, T3, T4, T5, T6, T7 ) detail::typelist< T1, variant_TL6( T2, T3, T4, T5, T6, T7 ) > + +// variant parameter unused type tags: + +template< class T > +struct TX : T +{ + inline TX operator+ ( ) const { return TX(); } + inline TX operator- ( ) const { return TX(); } + + inline TX operator! ( ) const { return TX(); } + inline TX operator~ ( ) const { return TX(); } + + inline TX*operator& ( ) const { return variant_nullptr; } + + template< class U > inline TX operator* ( U const & ) const { return TX(); } + template< class U > inline TX operator/ ( U const & ) const { return TX(); } + + template< class U > inline TX operator% ( U const & ) const { return TX(); } + template< class U > inline TX operator+ ( U const & ) const { return TX(); } + template< class U > inline TX operator- ( U const & ) const { return TX(); } + + template< class U > inline TX operator<<( U const & ) const { return TX(); } + template< class U > inline TX operator>>( U const & ) const { return TX(); } + + inline bool operator==( T const & ) const { return false; } + inline bool operator< ( T const & ) const { return false; } + + template< class U > inline TX operator& ( U const & ) const { return TX(); } + template< class U > inline TX operator| ( U const & ) const { return TX(); } + template< class U > inline TX operator^ ( U const & ) const { return TX(); } + + template< class U > inline TX operator&&( U const & ) const { return TX(); } + template< class U > inline TX operator||( U const & ) const { return TX(); } +}; + +struct S0{}; typedef TX T0; +struct S1{}; typedef TX T1; +struct S2{}; typedef TX T2; +struct S3{}; typedef TX T3; +struct S4{}; typedef TX T4; +struct S5{}; typedef TX T5; +struct S6{}; typedef TX T6; + +struct nulltype{}; + +template< class Head, class Tail > +struct typelist +{ + typedef Head head; + typedef Tail tail; +}; + +// typelist max element size: + +template< class List > +struct typelist_max; + +template <> +struct typelist_max< nulltype > +{ + enum { value = 0 } ; + typedef void type; +}; + +template< class Head, class Tail > +struct typelist_max< typelist > +{ +private: + enum { tail_value = size_t( typelist_max::value ) }; + + typedef typename typelist_max::type tail_type; + +public: + enum { value = (sizeof( Head ) > tail_value) ? sizeof( Head ) : std::size_t( tail_value ) } ; + + typedef typename conditional< (sizeof( Head ) > tail_value), Head, tail_type>::type type; +}; + +#if variant_CPP11_OR_GREATER + +// typelist max alignof element type: + +template< class List > +struct typelist_max_alignof; + +template <> +struct typelist_max_alignof< nulltype > +{ + enum { value = 0 } ; +}; + +template< class Head, class Tail > +struct typelist_max_alignof< typelist > +{ +private: + enum { tail_value = size_t( typelist_max_alignof::value ) }; + +public: + enum { value = (alignof( Head ) > tail_value) ? alignof( Head ) : std::size_t( tail_value ) }; +}; + +#endif + +// typelist size (length): + +template< class List > +struct typelist_size +{ + enum { value = 1 }; +}; + +template<> struct typelist_size< T0 > { enum { value = 0 }; }; +template<> struct typelist_size< T1 > { enum { value = 0 }; }; +template<> struct typelist_size< T2 > { enum { value = 0 }; }; +template<> struct typelist_size< T3 > { enum { value = 0 }; }; +template<> struct typelist_size< T4 > { enum { value = 0 }; }; +template<> struct typelist_size< T5 > { enum { value = 0 }; }; +template<> struct typelist_size< T6 > { enum { value = 0 }; }; + +template<> struct typelist_size< nulltype > { enum { value = 0 } ; }; + +template< class Head, class Tail > +struct typelist_size< typelist > +{ + enum { value = typelist_size::value + typelist_size::value }; +}; + +// typelist index of type: + +template< class List, class T > +struct typelist_index_of; + +template< class T > +struct typelist_index_of< nulltype, T > +{ + enum { value = -1 }; +}; + +template< class Tail, class T > +struct typelist_index_of< typelist, T > +{ + enum { value = 0 }; +}; + +template< class Head, class Tail, class T > +struct typelist_index_of< typelist, T > +{ +private: + enum { nextVal = typelist_index_of::value }; +public: + enum { value = nextVal == -1 ? -1 : 1 + nextVal } ; +}; + +// typelist type at index: + +template< class List, std::size_t i> +struct typelist_type_at; + +template< class Head, class Tail > +struct typelist_type_at< typelist, 0 > +{ + typedef Head type; +}; + +template< class Head, class Tail, std::size_t i > +struct typelist_type_at< typelist, i > +{ + typedef typename typelist_type_at::type type; +}; + +#if variant_CONFIG_MAX_ALIGN_HACK + +// Max align, use most restricted type for alignment: + +#define variant_UNIQUE( name ) variant_UNIQUE2( name, __LINE__ ) +#define variant_UNIQUE2( name, line ) variant_UNIQUE3( name, line ) +#define variant_UNIQUE3( name, line ) name ## line + +#define variant_ALIGN_TYPE( type ) \ + type variant_UNIQUE( _t ); struct_t< type > variant_UNIQUE( _st ) + +template< class T > +struct struct_t { T _; }; + +union max_align_t +{ + variant_ALIGN_TYPE( char ); + variant_ALIGN_TYPE( short int ); + variant_ALIGN_TYPE( int ); + variant_ALIGN_TYPE( long int ); + variant_ALIGN_TYPE( float ); + variant_ALIGN_TYPE( double ); + variant_ALIGN_TYPE( long double ); + variant_ALIGN_TYPE( char * ); + variant_ALIGN_TYPE( short int * ); + variant_ALIGN_TYPE( int * ); + variant_ALIGN_TYPE( long int * ); + variant_ALIGN_TYPE( float * ); + variant_ALIGN_TYPE( double * ); + variant_ALIGN_TYPE( long double * ); + variant_ALIGN_TYPE( void * ); + +#ifdef HAVE_LONG_LONG + variant_ALIGN_TYPE( long long ); +#endif + + struct Unknown; + + Unknown ( * variant_UNIQUE(_) )( Unknown ); + Unknown * Unknown::* variant_UNIQUE(_); + Unknown ( Unknown::* variant_UNIQUE(_) )( Unknown ); + + struct_t< Unknown ( * )( Unknown) > variant_UNIQUE(_); + struct_t< Unknown * Unknown::* > variant_UNIQUE(_); + struct_t< Unknown ( Unknown::* )(Unknown) > variant_UNIQUE(_); +}; + +#undef variant_UNIQUE +#undef variant_UNIQUE2 +#undef variant_UNIQUE3 + +#undef variant_ALIGN_TYPE + +#elif defined( variant_CONFIG_ALIGN_AS ) // variant_CONFIG_MAX_ALIGN_HACK + +// Use user-specified type for alignment: + +#define variant_ALIGN_AS( unused ) \ + variant_CONFIG_ALIGN_AS + +#else // variant_CONFIG_MAX_ALIGN_HACK + +// Determine POD type to use for alignment: + +#define variant_ALIGN_AS( to_align ) \ + typename detail::type_of_size< detail::alignment_types, detail::alignment_of< to_align >::value >::type + +template +struct alignment_of; + +template +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; + +template +struct alignment_logic +{ + enum { value = A < S ? A : S }; +}; + +template< typename T > +struct alignment_of +{ + enum { value = alignment_logic< + sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value, }; +}; + +template< typename List, size_t N > +struct type_of_size +{ + typedef typename conditional< + N == sizeof( typename List::head ), + typename List::head, + typename type_of_size::type >::type type; +}; + +template< size_t N > +struct type_of_size< nulltype, N > +{ + typedef variant_CONFIG_ALIGN_AS_FALLBACK type; +}; + +template< typename T> +struct struct_t { T _; }; + +#define variant_ALIGN_TYPE( type ) \ + typelist< type , typelist< struct_t< type > + +struct Unknown; + +typedef + variant_ALIGN_TYPE( char ), + variant_ALIGN_TYPE( short ), + variant_ALIGN_TYPE( int ), + variant_ALIGN_TYPE( long ), + variant_ALIGN_TYPE( float ), + variant_ALIGN_TYPE( double ), + variant_ALIGN_TYPE( long double ), + + variant_ALIGN_TYPE( char *), + variant_ALIGN_TYPE( short * ), + variant_ALIGN_TYPE( int * ), + variant_ALIGN_TYPE( long * ), + variant_ALIGN_TYPE( float * ), + variant_ALIGN_TYPE( double * ), + variant_ALIGN_TYPE( long double * ), + + variant_ALIGN_TYPE( Unknown ( * )( Unknown ) ), + variant_ALIGN_TYPE( Unknown * Unknown::* ), + variant_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), + + nulltype + > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + > > > > > > + alignment_types; + +#undef variant_ALIGN_TYPE + +#endif // variant_CONFIG_MAX_ALIGN_HACK + +template< typename T> +inline std::size_t hash( T const & v ) +{ + // primes: + unsigned const int a = 54059; + unsigned const int b = 76963; + unsigned const int h0 = 37; + + unsigned int h = h0; + unsigned char const * s = reinterpret_cast( &v ); + + for ( std::size_t i = 0; i < sizeof(v); ++i, ++s ) + { + h = (h * a) ^ (*s * b); + } + return h; +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +struct helper +{ + typedef signed char type_index_t; + typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types; + + template< class U > + static U * as( void * data ) + { + return reinterpret_cast( data ); + } + + template< class U > + static U const * as( void const * data ) + { + return reinterpret_cast( data ); + } + + static type_index_t to_index_t( std::size_t index ) + { + return static_cast( index ); + } + + static void destroy( std::size_t index, void * data ) + { + switch ( index ) + { + case 0: as( data )->~T0(); break; + case 1: as( data )->~T1(); break; + case 2: as( data )->~T2(); break; + case 3: as( data )->~T3(); break; + case 4: as( data )->~T4(); break; + case 5: as( data )->~T5(); break; + case 6: as( data )->~T6(); break; + } + } + +#if variant_CPP11_OR_GREATER + template< class T, class... Args > + static type_index_t construct_t( void * data, Args&&... args ) + { + new( data ) T( std::forward(args)... ); + + return to_index_t( detail::typelist_index_of< variant_types, T>::value ); + } + + template< std::size_t I, class... Args > + static type_index_t construct_i( void * data, Args&&... args ) + { + using type = typename detail::typelist_type_at< variant_types, I >::type; + + construct_t< type >( data, std::forward(args)... ); + + return to_index_t( I ); + } + + static type_index_t move( std::size_t const from_index, void * from_value, void * to_value ) + { + switch ( from_index ) + { + case 0: new( to_value ) T0( std::forward( *as( from_value ) ) ); break; + case 1: new( to_value ) T1( std::forward( *as( from_value ) ) ); break; + case 2: new( to_value ) T2( std::forward( *as( from_value ) ) ); break; + case 3: new( to_value ) T3( std::forward( *as( from_value ) ) ); break; + case 4: new( to_value ) T4( std::forward( *as( from_value ) ) ); break; + case 5: new( to_value ) T5( std::forward( *as( from_value ) ) ); break; + case 6: new( to_value ) T6( std::forward( *as( from_value ) ) ); break; + } + return to_index_t( from_index ); + } +#endif + + static type_index_t copy( std::size_t const from_index, const void * from_value, void * to_value ) + { + switch ( from_index ) + { + case 0: new( to_value ) T0( *as( from_value ) ); break; + case 1: new( to_value ) T1( *as( from_value ) ); break; + case 2: new( to_value ) T2( *as( from_value ) ); break; + case 3: new( to_value ) T3( *as( from_value ) ); break; + case 4: new( to_value ) T4( *as( from_value ) ); break; + case 5: new( to_value ) T5( *as( from_value ) ); break; + case 6: new( to_value ) T6( *as( from_value ) ); break; + } + return to_index_t( from_index ); + } +}; + +} // namespace detail + +// +// Variant: +// + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +class variant; + +class monostate{}; + +inline variant_constexpr bool operator< ( monostate, monostate ) variant_noexcept { return false; } +inline variant_constexpr bool operator> ( monostate, monostate ) variant_noexcept { return false; } +inline variant_constexpr bool operator<=( monostate, monostate ) variant_noexcept { return true; } +inline variant_constexpr bool operator>=( monostate, monostate ) variant_noexcept { return true; } +inline variant_constexpr bool operator==( monostate, monostate ) variant_noexcept { return true; } +inline variant_constexpr bool operator!=( monostate, monostate ) variant_noexcept { return false; } + +// obtain the size of the variant's list of alternatives at compile time + +template< class T > +struct variant_size; /* undefined */ + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +struct variant_size< variant > +{ + enum _ { value = detail::typelist_size< variant_TL7(T0, T1, T2, T3, T4, T5, T6) >::value }; +}; + +#if variant_CPP14_OR_GREATER +template< class T > +constexpr std::size_t variant_size_v = variant_size::value; +#endif + +#if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO +# define variant_size_V(T) nonstd::variant_size::value +#endif + +// obtain the type of the alternative specified by its index, at compile time: + +template< std::size_t I, class T > +struct variant_alternative; /* undefined */ + +template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +struct variant_alternative< I, variant > +{ + typedef typename detail::typelist_type_at::type type; +}; + +#if variant_CPP11_OR_GREATER +template< std::size_t I, class T > +using variant_alternative_t = typename variant_alternative::type; +#endif + +#if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO +# define variant_alternative_T(I,T) typename nonstd::variant_alternative::type +#endif + +// NTS:implement specializes the std::uses_allocator type trait +// std::uses_allocator + +// index of the variant in the invalid state (constant) + +#if variant_CPP11_OR_GREATER +variant_constexpr std::size_t variant_npos = static_cast( -1 ); +#else +static const std::size_t variant_npos = static_cast( -1 ); +#endif + +class bad_variant_access : public std::exception +{ +public: +#if variant_CPP11_OR_GREATER + virtual const char* what() const variant_noexcept variant_override +#else + virtual const char* what() const throw() +#endif + { + return "bad variant access"; + } +}; + +template< + class T0, + class T1 = detail::T1, + class T2 = detail::T2, + class T3 = detail::T3, + class T4 = detail::T4, + class T5 = detail::T5, + class T6 = detail::T6 +> +class variant +{ + typedef detail::helper< T0, T1, T2, T3, T4, T5, T6 > helper_type; + typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types; + +public: + variant() : type_index( 0 ) { new( ptr() ) T0(); } + + variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); } + variant( T1 const & t1 ) : type_index( 1 ) { new( ptr() ) T1( t1 ); } + variant( T2 const & t2 ) : type_index( 2 ) { new( ptr() ) T2( t2 ); } + variant( T3 const & t3 ) : type_index( 3 ) { new( ptr() ) T3( t3 ); } + variant( T4 const & t4 ) : type_index( 4 ) { new( ptr() ) T4( t4 ); } + variant( T5 const & t5 ) : type_index( 5 ) { new( ptr() ) T5( t5 ); } + variant( T6 const & t6 ) : type_index( 6 ) { new( ptr() ) T6( t6 ); } + +#if variant_CPP11_OR_GREATER + variant( T0 && t0 ) : type_index( 0 ) { new( ptr() ) T0( std::move( t0 ) ); } + variant( T1 && t1 ) : type_index( 1 ) { new( ptr() ) T1( std::move( t1 ) ); } + variant( T2 && t2 ) : type_index( 2 ) { new( ptr() ) T2( std::move( t2 ) ); } + variant( T3 && t3 ) : type_index( 3 ) { new( ptr() ) T3( std::move( t3 ) ); } + variant( T4 && t4 ) : type_index( 4 ) { new( ptr() ) T4( std::move( t4 ) ); } + variant( T5 && t5 ) : type_index( 5 ) { new( ptr() ) T5( std::move( t5 ) ); } + variant( T6 && t6 ) : type_index( 6 ) { new( ptr() ) T6( std::move( t6 ) ); } +#endif + + variant(variant const & rhs) + : type_index( rhs.type_index ) + { + (void) helper_type::copy( rhs.type_index, rhs.ptr(), ptr() ); + } + +#if variant_CPP11_OR_GREATER + + variant( variant && rhs ) + : type_index( rhs.type_index ) + { + (void) helper_type::move( rhs.type_index, rhs.ptr(), ptr() ); + } + + template< std::size_t I > + using type_at_t = typename detail::typelist_type_at< variant_types, I >::type; + + template< class T, class... Args, + typename = typename std::enable_if< std::is_constructible< T, Args...>::value>::type > + explicit variant( nonstd_lite_in_place_type_t(T), Args&&... args) + { + type_index = variant_npos_internal(); + type_index = helper_type::template construct_t( ptr(), std::forward(args)... ); + } + + template< class T, class U, class... Args, + typename = typename std::enable_if< std::is_constructible< T, std::initializer_list&, Args...>::value>::type > + explicit variant( nonstd_lite_in_place_type_t(T), std::initializer_list il, Args&&... args ) + { + type_index = variant_npos_internal(); + type_index = helper_type::template construct_t( ptr(), il, std::forward(args)... ); + } + + template< std::size_t I, class... Args, + typename = typename std::enable_if< std::is_constructible< type_at_t, Args...>::value>::type > + explicit variant( nonstd_lite_in_place_index_t(I), Args&&... args ) + { + type_index = variant_npos_internal(); + type_index = helper_type::template construct_i( ptr(), std::forward(args)... ); + } + + template , std::initializer_list&, Args...>::value >::type > + explicit variant( nonstd_lite_in_place_index_t(I), std::initializer_list il, Args&&... args ) + { + type_index = variant_npos_internal(); + type_index = helper_type::template construct_i( ptr(), il, std::forward(args)... ); + } + +#endif // variant_CPP11_OR_GREATER + + ~variant() + { + helper_type::destroy( index(), ptr() ); + } + + variant & operator=( variant const & rhs ) + { + return copy_assign( rhs ); + } + +#if variant_CPP11_OR_GREATER + + variant & operator=( variant && rhs ) + { + return move_assign( std::forward( rhs ) ); + } + + variant & operator=( T0 && t0 ) { return move_assign_value( std::forward( t0 ) ); } + variant & operator=( T1 && t1 ) { return move_assign_value( std::forward( t1 ) ); } + variant & operator=( T2 && t2 ) { return move_assign_value( std::forward( t2 ) ); } + variant & operator=( T3 && t3 ) { return move_assign_value( std::forward( t3 ) ); } + variant & operator=( T4 && t4 ) { return move_assign_value( std::forward( t4 ) ); } + variant & operator=( T5 && t5 ) { return move_assign_value( std::forward( t5 ) ); } + variant & operator=( T6 && t6 ) { return move_assign_value( std::forward( t6 ) ); } +#else + variant & operator=( T0 const & t0 ) { return copy_assign_value( t0 ); } + variant & operator=( T1 const & t1 ) { return copy_assign_value( t1 ); } + variant & operator=( T2 const & t2 ) { return copy_assign_value( t2 ); } + variant & operator=( T3 const & t3 ) { return copy_assign_value( t3 ); } + variant & operator=( T4 const & t4 ) { return copy_assign_value( t4 ); } + variant & operator=( T5 const & t5 ) { return copy_assign_value( t5 ); } + variant & operator=( T6 const & t6 ) { return copy_assign_value( t6 ); } +#endif + + std::size_t index() const + { + return variant_npos_internal() == type_index ? variant_npos : type_index; + } + + bool valueless_by_exception() const + { + return type_index == variant_npos_internal(); + } + +#if variant_CPP11_OR_GREATER + template< class T, class... Args, + typename = typename std::enable_if< std::is_constructible< T, Args...>::value>::type > + void emplace( Args&&... args ) + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + type_index = helper_type::template construct_t( ptr(), std::forward(args)... ); + } + + template< class T, class U, class... Args, + typename = typename std::enable_if< std::is_constructible< T, std::initializer_list&, Args...>::value>::type > + void emplace( std::initializer_list il, Args&&... args ) + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + type_index = helper_type::template construct_t( ptr(), il, std::forward(args)... ); + } + + template< size_t I, class... Args, + typename = typename std::enable_if< std::is_constructible< type_at_t, Args...>::value>::type > + void emplace( Args&&... args ) + { + this->template emplace< type_at_t >( std::forward(args)... ); + } + + template< size_t I, class U, class... Args, + typename = typename std::enable_if< std::is_constructible< type_at_t, std::initializer_list&, Args...>::value >::type > + void emplace( std::initializer_list il, Args&&... args ) + { + this->template emplace< type_at_t >( il, std::forward(args)... ); + } + +#endif // variant_CPP11_OR_GREATER + + void swap( variant & rhs ) variant_noexcept + { + if ( valueless_by_exception() && rhs.valueless_by_exception() ) + { + // no effect + } + else if ( index() == rhs.index() ) + { + this->swap_value( index(), rhs ); + } + else + { + variant tmp( *this ); + *this = rhs; + rhs = tmp; + } + } + + // + // non-standard: + // + + template< class T > + variant_constexpr std::size_t index_of() const variant_noexcept + { + return detail::typelist_index_of::type >::value; + } + + template< class T > + T & get() + { + const std::size_t i = index_of(); + + if ( i != index() || i == max_index() ) + { + throw bad_variant_access(); + } + + return *as(); + } + + template< class T > + T const & get() const + { + const std::size_t i = index_of(); + + if ( i != index() || i == max_index() ) + { + throw bad_variant_access(); + } + + return *as(); + } + + template< std::size_t I > + typename variant_alternative< I, variant >::type & + get() + { + return this->template get< typename detail::typelist_type_at< variant_types, I >::type >(); + } + + template< std::size_t I > + typename variant_alternative< I, variant >::type const & + get() const + { + return this->template get< typename detail::typelist_type_at< variant_types, I >::type >(); + } + +private: + typedef typename helper_type::type_index_t type_index_t; + + void * ptr() variant_noexcept + { + return &data; + } + + void const * ptr() const variant_noexcept + { + return &data; + } + + template< class U > + U * as() + { + return reinterpret_cast( ptr() ); + } + + template< class U > + U const * as() const + { + return reinterpret_cast( ptr() ); + } + + variant_constexpr std::size_t max_index() const variant_noexcept + { + return data_size; + } + + variant_constexpr type_index_t variant_npos_internal() const variant_noexcept + { + return static_cast( -1 ); + } + + variant & copy_assign( variant const & rhs ) + { + if ( valueless_by_exception() && rhs.valueless_by_exception() ) + { + // no effect + } + else if ( ! valueless_by_exception() && rhs.valueless_by_exception() ) + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + } + else if ( index() == rhs.index() ) + { + type_index = helper_type::copy( rhs.type_index, rhs.ptr(), ptr() ); + } + else + { + // alas exception safety with pre-C++11 needs an extra copy: + + variant tmp( rhs ); + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); +#if variant_CPP11_OR_GREATER + type_index = helper_type::move( rhs.type_index, tmp.ptr(), ptr() ); +#else + type_index = helper_type::copy( rhs.type_index, tmp.ptr(), ptr() ); +#endif + } + return *this; + } + +#if variant_CPP11_OR_GREATER + + variant & move_assign( variant && rhs ) + { + if ( valueless_by_exception() && rhs.valueless_by_exception() ) + { + // no effect + } + else if ( ! valueless_by_exception() && rhs.valueless_by_exception() ) + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + } + else if ( index() == rhs.index() ) + { + type_index = helper_type::move( rhs.type_index, rhs.ptr(), ptr() ); + } + else + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + type_index = helper_type::move( rhs.type_index, rhs.ptr(), ptr() ); + } + return *this; + } + + template< class T, std::size_t I > + variant & move_assign_value( T && value ) + { + if( index() == I ) + { + *as() = std::forward( value ); + } + else + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + new( ptr() ) T( std::forward( value ) ); + type_index = I; + } + return *this; + } +#else + template< class T, std::size_t I > + variant & copy_assign_value( T const & value ) + { + if( index() == I ) + { + *as() = value; + } + else + { + helper_type::destroy( type_index, ptr() ); + type_index = variant_npos_internal(); + new( ptr() ) T( value ); + type_index = I; + } + return *this; + } + +#endif // variant_CPP11_OR_GREATER + + void swap_value( std::size_t index, variant & rhs ) + { + using std::swap; + switch( index ) + { + case 0: swap( this->get<0>(), rhs.get<0>() ); break; + case 1: swap( this->get<1>(), rhs.get<1>() ); break; + case 2: swap( this->get<2>(), rhs.get<2>() ); break; + case 3: swap( this->get<3>(), rhs.get<3>() ); break; + case 4: swap( this->get<4>(), rhs.get<4>() ); break; + case 5: swap( this->get<5>(), rhs.get<5>() ); break; + case 6: swap( this->get<6>(), rhs.get<6>() ); break; + } + } + +private: + enum { data_size = detail::typelist_max< variant_types >::value }; + +#if variant_CPP11_OR_GREATER + + enum { data_align = detail::typelist_max_alignof< variant_types >::value }; + + using aligned_storage_t = typename std::aligned_storage< data_size, data_align >::type; + aligned_storage_t data; + +#elif variant_CONFIG_MAX_ALIGN_HACK + + typedef union { unsigned char data[ data_size ]; } aligned_storage_t; + + detail::max_align_t hack; + aligned_storage_t data; + +#else + typedef typename detail::typelist_max< variant_types >::type max_type; + + typedef variant_ALIGN_AS( max_type ) align_as_type; + + typedef union { align_as_type data[ 1 + ( data_size - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; + aligned_storage_t data; + +// # undef variant_ALIGN_AS + +#endif // variant_CONFIG_MAX_ALIGN_HACK + + type_index_t type_index; +}; + +template +inline bool holds_alternative( variant const & v ) variant_noexcept +{ + return v.index() == v.template index_of(); +} + +template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline R & get( variant & v, nonstd_lite_in_place_type_t(R) = in_place ) +{ + return v.template get(); +} + +template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline R const & get( variant const & v, nonstd_lite_in_place_type_t(R) = in_place ) +{ + return v.template get(); +} + +template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename variant_alternative< I, variant >::type & +get( variant & v, nonstd_lite_in_place_index_t(I) = in_place ) +{ + if ( I != v.index() ) + { + throw bad_variant_access(); + } + + return v.template get(); +} + +template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename variant_alternative< I, variant >::type const & +get( variant const & v, nonstd_lite_in_place_index_t(I) = in_place ) +{ + if ( I != v.index() ) + { + throw bad_variant_access(); + } + + return v.template get(); +} + +template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename detail::add_pointer::type +get_if( variant * pv, nonstd_lite_in_place_type_t(T) = in_place ) +{ + return ( pv->index() == pv->template index_of() ) ? &get( *pv ) : variant_nullptr; +} + +template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename detail::add_pointer::type +get_if( variant const * pv, nonstd_lite_in_place_type_t(T) = in_place) +{ + return ( pv->index() == pv->template index_of() ) ? &get( *pv ) : variant_nullptr; +} + +template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename detail::add_pointer< typename variant_alternative >::type >::type +get_if( variant * pv, nonstd_lite_in_place_index_t(I) = in_place ) +{ + return ( pv->index() == I ) ? &get( *pv ) : variant_nullptr; +} + +template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline typename detail::add_pointer< const typename variant_alternative >::type >::type +get_if( variant const * pv, nonstd_lite_in_place_index_t(I) = in_place ) +{ + return ( pv->index() == I ) ? &get( *pv ) : variant_nullptr; +} + +template< class T0, class T1, class T2, class T3, class T4, class T5 > +inline void swap( + variant & a, + variant & b ) variant_noexcept +{ + a.swap( b ); +} + +// template +// visit( Visitor&& vis, Variants&&... vars ); + +// The following visit is restricted with respect to the standard. +// It uses the common idiom is to return anrhs variant: + +template< class Visitor, class Variant > +inline Variant visit( Visitor const & vis, Variant const & v ) +{ + if ( v.valueless_by_exception() ) + { + throw bad_variant_access(); + } + + switch( v.index() ) + { + case 0: return vis( get<0>( v ) ); + case 1: return vis( get<1>( v ) ); + case 2: return vis( get<2>( v ) ); + case 3: return vis( get<3>( v ) ); + case 4: return vis( get<4>( v ) ); + case 5: return vis( get<5>( v ) ); + case 6: return vis( get<6>( v ) ); + default: return Variant(); + } +} + +namespace detail { + +template< class Variant > +struct Comparator +{ + static inline bool equal( Variant const & v, Variant const & w ) + { + switch( v.index() ) + { + case 0: return get<0>( v ) == get<0>( w ); + case 1: return get<1>( v ) == get<1>( w ); + case 2: return get<2>( v ) == get<2>( w ); + case 3: return get<3>( v ) == get<3>( w ); + case 4: return get<4>( v ) == get<4>( w ); + case 5: return get<5>( v ) == get<5>( w ); + case 6: return get<6>( v ) == get<6>( w ); + default: return false; + } + } + + static inline bool less_than( Variant const & v, Variant const & w ) + { + switch( v.index() ) + { + case 0: return get<0>( v ) < get<0>( w ); + case 1: return get<1>( v ) < get<1>( w ); + case 2: return get<2>( v ) < get<2>( w ); + case 3: return get<3>( v ) < get<3>( w ); + case 4: return get<4>( v ) < get<4>( w ); + case 5: return get<5>( v ) < get<5>( w ); + case 6: return get<6>( v ) < get<6>( w ); + default: return false; + } + } +}; + +} //namespace detail + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator==( + variant const & v, + variant const & w ) +{ + if ( v.index() != w.index() ) return false; + else if ( v.valueless_by_exception() ) return true; + else return detail::Comparator< variant >::equal( v, w ); +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator!=( + variant const & v, + variant const & w ) +{ + return ! ( v == w ); +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator<( + variant const & v, + variant const & w ) +{ + if ( w.valueless_by_exception() ) return false; + else if ( v.valueless_by_exception() ) return true; + else if ( v.index() < w.index() ) return true; + else if ( v.index() > w.index() ) return false; + else return detail::Comparator< variant >::less_than( v, w ); +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator>( + variant const & v, + variant const & w ) +{ + return w < v; +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator<=( + variant const & v, + variant const & w ) +{ + return ! ( v > w ); +} + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +inline bool operator>=( + variant const & v, + variant const & w ) +{ + return ! ( v < w ); +} + +} // namespace variants + +using namespace variants; + +} // namespace nonstd + +#if variant_CPP11_OR_GREATER + +// specialize the std::hash algorithm: + +namespace std { + +template<> +struct hash< nonstd::monostate > +{ + std::size_t operator()( nonstd::monostate ) const variant_noexcept + { + return 42; + } +}; + +template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 > +struct hash< nonstd::variant > +{ + std::size_t operator()( nonstd::variant const & v ) const variant_noexcept + { + return nonstd::variants::detail::hash( v ); + } +}; + +} //namespace std + +#endif // variant_CPP11_OR_GREATER + +#if variant_BETWEEN(variant_COMPILER_MSVC_VERSION, 10, 14 ) +# pragma warning( pop ) +#endif + +#endif // have C++17 std::variant + +#endif // NONSTD_VARIANT_LITE_HPP \ No newline at end of file diff --git a/tools/settingsgenerator/main.cpp b/tools/settingsgenerator/main.cpp index 8bfcb6b..df1226c 100644 --- a/tools/settingsgenerator/main.cpp +++ b/tools/settingsgenerator/main.cpp @@ -44,11 +44,10 @@ int main(int argc, char *argv[]) try { SettingsGenerator generator { - parser.value(QStringLiteral("in")), parser.value(QStringLiteral("header")), parser.value(QStringLiteral("impl")) }; - generator.process(); + generator.process(parser.value(QStringLiteral("in"))); return EXIT_SUCCESS; } catch (const QString &str) { qCritical() << qUtf8Printable(str); diff --git a/tools/settingsgenerator/qpmx.json b/tools/settingsgenerator/qpmx.json new file mode 100644 index 0000000..5f052db --- /dev/null +++ b/tools/settingsgenerator/qpmx.json @@ -0,0 +1,21 @@ +{ + "dependencies": [ + { + "package": "de.skycoder42.qxmlcodegen", + "provider": "qpm", + "version": "1.0.0" + } + ], + "license": { + "file": "", + "name": "" + }, + "prcFile": "", + "priFile": "", + "priIncludes": [ + ], + "publishers": { + }, + "qbsFile": "", + "source": false +} diff --git a/tools/settingsgenerator/qsettingsgenerator.xsd b/tools/settingsgenerator/qsettingsgenerator.xsd index 3dc8ea9..b7d844c 100644 --- a/tools/settingsgenerator/qsettingsgenerator.xsd +++ b/tools/settingsgenerator/qsettingsgenerator.xsd @@ -1,32 +1,45 @@ + + + + QtCore/QHash + + - - + - + - + - + - + + + + + + + - + @@ -34,49 +47,49 @@ - + - + - + - + - - - - + + + + + + + + - + - + - + - + - - - - - - - - + + + + @@ -84,5 +97,5 @@ - + diff --git a/tools/settingsgenerator/settingsgenerator.cpp b/tools/settingsgenerator/settingsgenerator.cpp index 014eafe..a3a1540 100644 --- a/tools/settingsgenerator/settingsgenerator.cpp +++ b/tools/settingsgenerator/settingsgenerator.cpp @@ -5,218 +5,39 @@ #define TABS QString{QLatin1Char('\t')}.repeated(intendent) -SettingsGenerator::SettingsGenerator(const QString &inPath, const QString &hdrPath, const QString &srcPath) : - _inFile{inPath}, +SettingsGenerator::SettingsGenerator(const QString &hdrPath, const QString &srcPath) : _hdrFile{hdrPath}, _srcFile{srcPath}, - _xml{&_inFile}, _hdr{&_hdrFile}, _src{&_srcFile} {} -void SettingsGenerator::process() +void SettingsGenerator::process(const QString &inPath) { - if(!_inFile.open(QIODevice::ReadOnly | QIODevice::Text)) - throwFile(_inFile); - if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) - throwFile(_hdrFile); - if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) - throwFile(_srcFile); - - if(!_xml.readNextStartElement()) - throwReader(_xml); - if(_xml.name() != QStringLiteral("Settings")) - throwChild(_xml); - auto data = readSettings(_xml); - checkError(_xml); - qDebug() << "Completed parsing xml - it is valid"; - - data.includes.append({ - {false, QStringLiteral("QtCore/QObject")}, - {false, QStringLiteral("QtMvvmCore/ISettingsAccessor")}, - {false, QStringLiteral("QtMvvmCore/SettingsEntry")}, - }); - - writeHeader(data); - writeSource(data); -} - -SettingsGenerator::Include SettingsGenerator::readInclude(QXmlStreamReader &xml) -{ - Include include; - include.local = readAttrib(xml, QStringLiteral("local"), false); - include.include = xml.readElementText(); - checkError(xml); - return include; -} - -SettingsGenerator::Param SettingsGenerator::readParam(QXmlStreamReader &xml) -{ - Param param; - param.key = readAttrib(xml, QStringLiteral("key"), {}, true); - param.type = readAttrib(xml, QStringLiteral("type"), {}, true); - param.asStr = readAttrib(xml, QStringLiteral("asStr"), false); - param.value = xml.readElementText(); - checkError(xml); - return param; -} - -QSharedPointer SettingsGenerator::readBackend(QXmlStreamReader &xml) -{ - auto backend = QSharedPointer::create(); - backend->className = readAttrib(xml, QStringLiteral("class"), {}, true); - while(xml.readNextStartElement()) { - if(xml.name() == QStringLiteral("Param")) - backend->params.append(readParam(xml)); - else - throwChild(xml); - } - checkError(xml); - return backend; -} - -QPair SettingsGenerator::readTypeMapping(QXmlStreamReader &xml) -{ - QPair mapping; - mapping.first = readAttrib(xml, QStringLiteral("key"), {}, true); - mapping.second = readAttrib(xml, QStringLiteral("type"), {}, true); - checkError(xml); - return mapping; -} - -SettingsGenerator::Node SettingsGenerator::readNode(QXmlStreamReader &xml) -{ - Node node; - node.key = readAttrib(xml, QStringLiteral("key"), {}, true); - while(xml.readNextStartElement()) { - if(xml.name() == QStringLiteral("Node")) - node.subNodes.append(readNode(xml)); - else if(xml.name() == QStringLiteral("Entry")) - node.subEntries.append(readEntry(xml)); - else if(xml.name() == QStringLiteral("Import")) - node.subImports.append(readImport(xml)); - else - throwChild(xml); - } - checkError(xml); - return node; -} - -SettingsGenerator::Entry SettingsGenerator::readEntry(QXmlStreamReader &xml) -{ - Entry entry; - entry.key = readAttrib(xml, QStringLiteral("key"), {}, true); - entry.type = readAttrib(xml, QStringLiteral("type"), {}, true); - entry.qmlGroupKey = readAttrib(xml, QStringLiteral("qmlGroupKey")); - entry.defaultValue = readAttrib(xml, QStringLiteral("default")); - entry.tr = readAttrib(xml, QStringLiteral("tr"), false); - entry.trContext = readAttrib(xml, QStringLiteral("trContext")); - while(xml.readNextStartElement()) { - if(xml.name() == QStringLiteral("Code")) { - if(!entry.defaultValue.isNull()) - throwChild(xml); - entry.defaultValue = xml.readElementText(); - entry.defaultIsCode = true; - checkError(xml); - } else if(xml.name() == QStringLiteral("Node")) - entry.subNodes.append(readNode(xml)); - else if(xml.name() == QStringLiteral("Entry")) - entry.subEntries.append(readEntry(xml)); - else if(xml.name() == QStringLiteral("Import")) - entry.subImports.append(readImport(xml)); - else - throwChild(xml); - } - checkError(xml); - return entry; -} - -SettingsGenerator::Import SettingsGenerator::readImport(QXmlStreamReader &xml) -{ - auto required = readAttrib(xml, QStringLiteral("required"), true); - auto rootNode = readAttrib(xml, QStringLiteral("rootNode")).split(QLatin1Char('/'), QString::SkipEmptyParts); - auto path = xml.readElementText(); - checkError(xml); - - auto pInfo = QFileInfo{static_cast(xml.device())->fileName()}.dir(); - QFile subFile{pInfo.absoluteFilePath(path)}; - if(!subFile.exists()) { - if(required) - throwReader(xml, QStringLiteral("Failed to find required import file \"%1\"").arg(subFile.fileName())); - else - return {}; - } + // TODO add xml patterns... + auto settings = readDocument(inPath); - if(!subFile.open(QIODevice::ReadOnly | QIODevice::Text)) - throwFile(subFile); - - //TODO implement - - QXmlStreamReader reader{&subFile}; - if(!reader.readNextStartElement()) - throwReader(reader); - if(reader.name() != QStringLiteral("Settings")) - throwChild(reader); - Node subSettings = readSettings(reader); - checkError(reader); - for(const auto &key : rootNode) { - auto found = false; - for(const auto &sNode : qAsConst(subSettings.subNodes)) { - if(sNode.key == key) { - found = true; - subSettings = sNode; - break; - } - } - for(const auto &sNode : qAsConst(subSettings.subEntries)) { - if(sNode.key == key) { - found = true; - subSettings = sNode; - break; - } - } - for(const auto &sNode : qAsConst(subSettings.subImports)) { - if(sNode.key == key) { - found = true; - subSettings = sNode; - break; - } - } - if(!found) - throwReader(xml, QStringLiteral("Unable to find rootNode \"%1\" in loaded document").arg(rootNode.join(QLatin1Char('/')))); - } + if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) + throw FileException{_hdrFile}; + writeHeader(settings); + _hdrFile.close(); - return std::move(subSettings); + if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) + throw FileException{_srcFile}; + writeSource(settings); + _srcFile.close(); } -SettingsGenerator::Settings SettingsGenerator::readSettings(QXmlStreamReader &xml) +bool SettingsGenerator::read_type_mapping(QXmlStreamReader &reader, QHash &data, bool hasNext) { - Settings settings; - settings.name = readAttrib(xml, QStringLiteral("name"), {}, true); - settings.prefix = readAttrib(xml, QStringLiteral("prefix")); - - while(xml.readNextStartElement()) { - if(xml.name() == QStringLiteral("Include")) - settings.includes.append(readInclude(xml)); - else if(xml.name() == QStringLiteral("Backend")) - settings.backend = readBackend(xml); - else if(xml.name() == QStringLiteral("TypeMapping")) { - auto mapping = readTypeMapping(xml); - settings.typeMapping.insert(mapping.first, mapping.second); - } else if(xml.name() == QStringLiteral("Node")) - settings.subNodes.append(readNode(xml)); - else if(xml.name() == QStringLiteral("Entry")) - settings.subEntries.append(readEntry(xml)); - else if(xml.name() == QStringLiteral("Import")) - settings.subImports.append(readImport(xml)); - else - throwChild(xml); - } - checkError(xml); - return settings; + TypeMappingGroup grp; + hasNext = read_TypeMappingGroup(reader, grp, hasNext); + for(const auto &mapping : qAsConst(grp.typeMapping)) + data.insert(mapping.key, mapping.type); + return hasNext; } -void SettingsGenerator::writeHeader(const Settings &settings) +void SettingsGenerator::writeHeader(const SettingsType &settings) { QString incGuard = QFileInfo{_hdrFile.fileName()} .completeBaseName() @@ -235,15 +56,15 @@ void SettingsGenerator::writeHeader(const Settings &settings) _hdr << "\n"; // create the class - QString pName = settings.prefix.isEmpty() ? settings.name : (settings.prefix + QLatin1Char(' ') + settings.name); - _hdr << "class " << pName << " : public QObject\n" + auto name = settings.name.value_or(QFileInfo{_hdrFile.fileName()}.baseName()); + _hdr << "class " << QString{settings.prefix ? settings.prefix.value() + QLatin1Char(' ') + name : name} << " : public QObject\n" << "{\n" << "\tQ_OBJECT\n\n" << "\tQ_PROPERTY(ISettingsAccessor *accessor READ accessor CONSTANT FINAL)\n\n" << "public:\n" - << "\tQ_INVOKABLE explicit " << settings.name << "(QObject *parent = nullptr);\n" - << "\texplicit " << settings.name << "(QObject *parent, ISettingsAccessor *accessor);\n\n" - << "\tstatic " << settings.name << " *instance();\n\n" + << "\tQ_INVOKABLE explicit " << name << "(QObject *parent = nullptr);\n" + << "\texplicit " << name << "(QObject *parent, ISettingsAccessor *accessor);\n\n" + << "\tstatic " << name << " *instance();\n\n" << "\tISettingsAccessor *accessor() const;\n\n"; writeNodeElements(settings); @@ -254,81 +75,29 @@ void SettingsGenerator::writeHeader(const Settings &settings) << "#endif //" << incGuard << '\n'; } -void SettingsGenerator::writeNodeElements(const SettingsGenerator::Node &node, int intendent) +void SettingsGenerator::writeNodeElements(const NodeContentGroup &node, int intendent) { - for(const auto &cNode : node.subNodes) + for(const auto &cNode : node.nodes) writeNode(cNode, intendent); - for(const auto &cEntry : node.subEntries) + for(const auto &cEntry : node.entries) writeEntry(cEntry, intendent); } -void SettingsGenerator::writeNode(const SettingsGenerator::Node &node, int intendent) +void SettingsGenerator::writeNode(const NodeType &node, int intendent) { _hdr << TABS << "struct {\n"; writeNodeElements(node, intendent + 1); _hdr << TABS << "} " << node.key << ";\n"; } -void SettingsGenerator::writeEntry(const SettingsGenerator::Entry &entry, int intendent) +void SettingsGenerator::writeEntry(const EntryType &entry, int intendent) { _hdr << TABS << "struct : QtMvvm::SettingsEntry<" << entry.type << "> {\n"; writeNodeElements(entry, intendent + 1); _hdr << TABS << "} " << entry.key << ";\n"; } -void SettingsGenerator::writeSource(const Settings &settings) +void SettingsGenerator::writeSource(const SettingsType &settings) { } - -void SettingsGenerator::checkError(QXmlStreamReader &xml) const -{ - if(xml.hasError()) - throwReader(xml); -} - -template -T SettingsGenerator::readAttrib(QXmlStreamReader &xml, const QString &key, const T &defaultValue, bool required) const -{ - if(xml.attributes().hasAttribute(key)) - return QVariant(xml.attributes().value(key).toString()).template value(); - else if(required) - throwReader(xml, QStringLiteral("Required attribute \"%1\" but was not set").arg(key)); - else - return defaultValue; -} - -template<> -bool SettingsGenerator::readAttrib(QXmlStreamReader &xml, const QString &key, const bool &defaultValue, bool required) const -{ - if(xml.attributes().hasAttribute(key)) { - if(xml.attributes().value(key) == QStringLiteral("true")) - return true; - else if(xml.attributes().value(key) == QStringLiteral("false")) - return false; - else - throwReader(xml, QStringLiteral("Value of attribute \"%1\" is not a xs:boolean!").arg(key)); - } else if(required) - throwReader(xml, QStringLiteral("Required attribute \"%1\" but was not set").arg(key)); - else - return defaultValue; -} - -void SettingsGenerator::throwFile(const QFileDevice &file) const -{ - throw QStringLiteral("%1: %2").arg(file.fileName(), file.errorString()); -} - -void SettingsGenerator::throwReader(QXmlStreamReader &xml, const QString &overwriteError) const -{ - throw QStringLiteral("%1:%2:%3: %4") - .arg(dynamic_cast(xml.device())->fileName()) - .arg(xml.lineNumber()) - .arg(xml.columnNumber()) - .arg(overwriteError.isNull() ? xml.errorString() : overwriteError); -} - -void SettingsGenerator::throwChild(QXmlStreamReader &xml) -{ - throwReader(xml, QStringLiteral("Unexpected child element: %1").arg(xml.name())); -} diff --git a/tools/settingsgenerator/settingsgenerator.h b/tools/settingsgenerator/settingsgenerator.h index 70c7d31..1d5c5b6 100644 --- a/tools/settingsgenerator/settingsgenerator.h +++ b/tools/settingsgenerator/settingsgenerator.h @@ -2,108 +2,34 @@ #define SETTINGSGENERATOR_H #include -#include #include -#include -class SettingsGenerator +#include "qsettingsgenerator.h" + +class SettingsGenerator : public SettingsGeneratorBase { public: - SettingsGenerator(const QString &inPath, - const QString &hdrPath, + SettingsGenerator(const QString &hdrPath, const QString &srcPath); - void process(); + void process(const QString &inPath); + +protected: + bool read_type_mapping(QXmlStreamReader &reader, QHash &data, bool hasNext) override; private: - QFile _inFile; QFile _hdrFile; QFile _srcFile; - QXmlStreamReader _xml; QTextStream _hdr; QTextStream _src; - struct Include{ - bool local; - QString include; - }; - - struct Param { - QString key; - QString type; - bool asStr; - QString value; - }; - - struct Backend { - QString className; - QList params; - }; - - struct Entry; - struct Import; - struct Node { - QString key; - QList subNodes; - QList subEntries; - QList subImports; - }; - - struct Entry : public Node { - QString type; - QString qmlGroupKey; - QString defaultValue; - bool defaultIsCode = false; - bool tr; - QString trContext; - }; - - struct Import : public Node { - inline Import() = default; - inline Import(Node &&node) : - Node(std::move(node)) - {} - }; - - struct Settings : public Node { - QString name; - QString prefix; - QString baseKey; + void writeHeader(const SettingsType &settings); + void writeNodeElements(const NodeContentGroup &node, int intendent = 1); + void writeNode(const NodeType &node, int intendent = 1); + void writeEntry(const EntryType &entry, int intendent = 1); - QList includes; - QSharedPointer backend; - QHash typeMapping; - }; - - Include readInclude(QXmlStreamReader &xml); - Param readParam(QXmlStreamReader &xml); - QSharedPointer readBackend(QXmlStreamReader &xml); - QPair readTypeMapping(QXmlStreamReader &xml); - - Node readNode(QXmlStreamReader &xml); - Entry readEntry(QXmlStreamReader &xml); - Import readImport(QXmlStreamReader &xml); - - Settings readSettings(QXmlStreamReader &xml); - - void writeHeader(const Settings &settings); - void writeNodeElements(const Node &node, int intendent = 1); - void writeNode(const Node &node, int intendent = 1); - void writeEntry(const Entry &entry, int intendent = 1); - - void writeSource(const Settings &settings); - - template - T readAttrib(QXmlStreamReader &xml, const QString &key, const T &defaultValue = {}, bool required = false) const; - - void checkError(QXmlStreamReader &xml) const; - Q_NORETURN void throwFile(const QFileDevice &file) const; - Q_NORETURN void throwReader(QXmlStreamReader &xml, const QString &overwriteError = {}) const; - Q_NORETURN void throwChild(QXmlStreamReader &xml); + void writeSource(const SettingsType &settings); }; -template<> -bool SettingsGenerator::readAttrib(QXmlStreamReader &xml, const QString &key, const bool &defaultValue, bool required) const; - #endif // SETTINGSGENERATOR_H diff --git a/tools/settingsgenerator/settingsgenerator.pro b/tools/settingsgenerator/settingsgenerator.pro index f203896..774575c 100644 --- a/tools/settingsgenerator/settingsgenerator.pro +++ b/tools/settingsgenerator/settingsgenerator.pro @@ -14,11 +14,15 @@ DEFINES += "COMPANY=\\\"$$COMPANY\\\"" DEFINES += "BUNDLE_PREFIX=\\\"$$BUNDLE_PREFIX\\\"" HEADERS += \ - settingsgenerator.h + settingsgenerator.h SOURCES += \ main.cpp \ - settingsgenerator.cpp + settingsgenerator.cpp + +XML_SCHEMA_DEFINITIONS += qsettingsgenerator.xsd + +include(../3rdparty/3rdparty.pri) load(qt_tool) @@ -30,4 +34,5 @@ win32 { QMAKE_TARGET_BUNDLE_PREFIX = $${BUNDLE_PREFIX}. } -DISTFILES += qsettingsgenerator.xsd +!ReleaseBuild:!DebugBuild:!system(qpmx -d $$shell_quote($$_PRO_FILE_PWD_) --qmake-run init $$QPMX_EXTRA_OPTIONS $$shell_quote($$QMAKE_QMAKE) $$shell_quote($$OUT_PWD)): error(qpmx initialization failed. Check the compilation log for details.) +else: include($$OUT_PWD/qpmx_generated.pri)