mirror of
https://github.com/ToruNiina/toml11.git
synced 2024-11-08 22:00:07 +00:00
add acceptors for toml values
This commit is contained in:
parent
3e016be668
commit
50d00a840f
@ -37,29 +37,247 @@ inline wrapping_iterator<T> wrap(T v) {return wrapping_iterator<T>(v);}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_conditions)
|
||||
{
|
||||
BOOST_CHECK( toml::is_space::invoke(wrap(' ')));
|
||||
BOOST_CHECK(!toml::is_space::invoke(wrap('a')));
|
||||
BOOST_CHECK( toml::is_space<char>::invoke(wrap(' ')));
|
||||
BOOST_CHECK(!toml::is_space<char>::invoke(wrap('a')));
|
||||
|
||||
BOOST_CHECK( toml::is_tab::invoke(wrap('\t')));
|
||||
BOOST_CHECK(!toml::is_tab::invoke(wrap('a')));
|
||||
BOOST_CHECK( toml::is_tab<char>::invoke(wrap('\t')));
|
||||
BOOST_CHECK(!toml::is_tab<char>::invoke(wrap('a')));
|
||||
|
||||
for(char c = '0'; c <= '9'; ++c)
|
||||
BOOST_CHECK(toml::is_number::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_number::invoke(wrap('a')));
|
||||
BOOST_CHECK(toml::is_number<char>::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_number<char>::invoke(wrap('a')));
|
||||
|
||||
for(char c = 'a'; c <= 'z'; ++c)
|
||||
BOOST_CHECK(toml::is_lowercase::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_lowercase::invoke(wrap('A')));
|
||||
BOOST_CHECK(toml::is_lowercase<char>::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_lowercase<char>::invoke(wrap('A')));
|
||||
|
||||
for(char c = 'A'; c <= 'Z'; ++c)
|
||||
BOOST_CHECK(toml::is_uppercase::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_uppercase::invoke(wrap('a')));
|
||||
BOOST_CHECK(toml::is_uppercase<char>::invoke(wrap(c)));
|
||||
BOOST_CHECK(!toml::is_uppercase<char>::invoke(wrap('a')));
|
||||
|
||||
BOOST_CHECK(toml::is_whitespace::invoke(wrap(' ')));
|
||||
BOOST_CHECK(toml::is_whitespace::invoke(wrap('\t')));
|
||||
BOOST_CHECK(toml::is_whitespace<char>::invoke(wrap(' ')));
|
||||
BOOST_CHECK(toml::is_whitespace<char>::invoke(wrap('\t')));
|
||||
|
||||
std::string barekey("hoge1-piyo2_fuga3");
|
||||
BOOST_CHECK(toml::is_barekey::invoke(barekey.cbegin()) == barekey.cend());
|
||||
BOOST_CHECK(toml::is_barekey<char>::invoke(barekey.cbegin()) == barekey.cend());
|
||||
std::string partial("hoge1.piyo2_fuga3");
|
||||
BOOST_CHECK(toml::is_barekey::invoke(partial.cbegin()) == partial.cbegin()+5);
|
||||
BOOST_CHECK(toml::is_barekey<char>::invoke(partial.cbegin()) == partial.cbegin()+5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_basic_inline_string)
|
||||
{
|
||||
using is_valid = toml::is_basic_inline_string<char>;
|
||||
{
|
||||
const std::string simple("\"hoge1-piyo2_fuga3\"");
|
||||
BOOST_CHECK(is_valid::invoke(simple.cbegin()) == simple.cend());
|
||||
}
|
||||
{
|
||||
const std::string quote("\"hoge1-\\\"piyo2\\\"_fuga3\"");
|
||||
BOOST_CHECK(is_valid::invoke(quote.cbegin()) == quote.cend());
|
||||
}
|
||||
{
|
||||
const std::string escape("\"I'm a string. \\\"You can quote me\\\". Name\\tJos\\u00E9\\nLocation\\tSF.\"");
|
||||
BOOST_CHECK(is_valid::invoke(escape.cbegin()) == escape.cend());
|
||||
}
|
||||
{
|
||||
const std::string empty("\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(empty.cbegin()) == empty.cend());
|
||||
}
|
||||
|
||||
{
|
||||
const std::string newline("\"newline\r\nhoge\"");
|
||||
BOOST_CHECK(is_valid::invoke(newline.cbegin()) == newline.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string invalid_escape("\"foo\\abar\"");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_escape.cbegin()) == invalid_escape.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string invalid_charactor("\"foo\0bar\"");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_charactor.cbegin()) == invalid_charactor.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string multi("\"\"\"multiline\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(multi.cbegin()) == multi.cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_basic_multiline_string)
|
||||
{
|
||||
using is_valid = toml::is_basic_multiline_string<char>;
|
||||
{
|
||||
const std::string simple("\"\"\"foobar\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(simple.cbegin()) == simple.cend());
|
||||
}
|
||||
{
|
||||
const std::string quote("\"\"\"hoge1-\"piyo2\"_fuga3\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(quote.cbegin()) == quote.cend());
|
||||
}
|
||||
{
|
||||
const std::string newline("\"\"\"hoge1-\npiyo2_\r\nfuga3\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(newline.cbegin()) == newline.cend());
|
||||
}
|
||||
{
|
||||
const std::string escape("\"\"\"I'm a string. \"You can quote me\". Name\\tJos\\u00E9\\nLocation\\tSF.\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(escape.cbegin()) == escape.cend());
|
||||
}
|
||||
{
|
||||
const std::string empty("\"\"\"\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(empty.cbegin()) == empty.cend());
|
||||
}
|
||||
{
|
||||
const std::string ending_backslash("\"\"\"hoge\\\n piyo\\\n\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(ending_backslash.cbegin()) == ending_backslash.cend());
|
||||
}
|
||||
|
||||
{
|
||||
const std::string invalid_escape("\"\"\"foo\\abar\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_escape.cbegin()) == invalid_escape.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string invalid_charactor("\"\"\"foo\0bar\"\"\"");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_charactor.cbegin()) == invalid_charactor.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string single("\"singleline\"");
|
||||
BOOST_CHECK(is_valid::invoke(single.cbegin()) == single.cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_literal_inline_string)
|
||||
{
|
||||
using is_valid = toml::is_literal_inline_string<char>;
|
||||
{
|
||||
const std::string simple("'foobar'");
|
||||
BOOST_CHECK(is_valid::invoke(simple.cbegin()) == simple.cend());
|
||||
}
|
||||
{
|
||||
const std::string nonescape("'C:\\Users\\nodejs\\templates'");
|
||||
BOOST_CHECK(is_valid::invoke(nonescape.cbegin()) == nonescape.cend());
|
||||
}
|
||||
{
|
||||
const std::string empty("''");
|
||||
BOOST_CHECK(is_valid::invoke(empty.cbegin()) == empty.cend());
|
||||
}
|
||||
|
||||
{
|
||||
const std::string quote("'hoge1-'piyo2'_fuga3'");
|
||||
BOOST_CHECK(is_valid::invoke(quote.cbegin()) == quote.cbegin() + 8);
|
||||
}
|
||||
{
|
||||
const std::string newline("'hoge1-\npiyo2_\r\nfuga3'");
|
||||
BOOST_CHECK(is_valid::invoke(newline.cbegin()) == newline.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string invalid_charactor("'foo\0bar'");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_charactor.cbegin()) == invalid_charactor.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string multi("'''multiline'''");
|
||||
BOOST_CHECK(is_valid::invoke(multi.cbegin()) == multi.cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_literal_multiline_string)
|
||||
{
|
||||
using is_valid = toml::is_literal_multiline_string<char>;
|
||||
{
|
||||
const std::string simple("'''foobar'''");
|
||||
BOOST_CHECK(is_valid::invoke(simple.cbegin()) == simple.cend());
|
||||
}
|
||||
{
|
||||
const std::string quote("'''hoge1-'piyo2'_fuga3'''");
|
||||
BOOST_CHECK(is_valid::invoke(quote.cbegin()) == quote.cend());
|
||||
}
|
||||
{
|
||||
const std::string nonescape("'''C:\\Users\\nodejs\\templates'''");
|
||||
BOOST_CHECK(is_valid::invoke(nonescape.cbegin()) == nonescape.cend());
|
||||
}
|
||||
{
|
||||
const std::string newline("'''hoge1-\npiyo2_\r\nfuga3'''");
|
||||
BOOST_CHECK(is_valid::invoke(newline.cbegin()) == newline.cend());
|
||||
}
|
||||
{
|
||||
const std::string empty("''''''");
|
||||
BOOST_CHECK(is_valid::invoke(empty.cbegin()) == empty.cend());
|
||||
}
|
||||
|
||||
{
|
||||
const std::string invalid_charactor("'''foo\0bar'''");
|
||||
BOOST_CHECK(is_valid::invoke(invalid_charactor.cbegin()) == invalid_charactor.cbegin());
|
||||
}
|
||||
{
|
||||
const std::string single("'singleline'");
|
||||
BOOST_CHECK(is_valid::invoke(single.cbegin()) == single.cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_integer)
|
||||
{
|
||||
using is_valid = toml::is_integer<char>;
|
||||
{
|
||||
const std::string simple("1");
|
||||
BOOST_CHECK(is_valid::invoke(simple.cbegin()) == simple.cend());
|
||||
}
|
||||
{
|
||||
const std::string psign("+1234");
|
||||
BOOST_CHECK(is_valid::invoke(psign.cbegin()) == psign.cend());
|
||||
const std::string nsign("-1234");
|
||||
BOOST_CHECK(is_valid::invoke(nsign.cbegin()) == nsign.cend());
|
||||
}
|
||||
{
|
||||
const std::string zero("0");
|
||||
BOOST_CHECK(is_valid::invoke(zero.cbegin()) == zero.cend());
|
||||
}
|
||||
{
|
||||
const std::string us("1_2_3_4_5");
|
||||
BOOST_CHECK(is_valid::invoke(us.cbegin()) == us.cend());
|
||||
}
|
||||
|
||||
{
|
||||
const std::string f("12.34");
|
||||
BOOST_CHECK(is_valid::invoke(f.cbegin()) == f.cbegin()+2);
|
||||
}
|
||||
{
|
||||
const std::string f("12e34");
|
||||
BOOST_CHECK(is_valid::invoke(f.cbegin()) == f.cbegin()+2);
|
||||
}
|
||||
{
|
||||
const std::string ascii("1234a");
|
||||
BOOST_CHECK(is_valid::invoke(ascii.cbegin()) == ascii.cbegin()+4);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_float)
|
||||
{
|
||||
using is_valid = toml::is_float<char>;
|
||||
{
|
||||
const std::string simplef("1.0");
|
||||
BOOST_CHECK(is_valid::invoke(simplef.cbegin()) == simplef.cend());
|
||||
const std::string simplee("1e0");
|
||||
BOOST_CHECK(is_valid::invoke(simplee.cbegin()) == simplee.cend());
|
||||
const std::string both("6.626e-34");
|
||||
BOOST_CHECK(is_valid::invoke(both.cbegin()) == both.cend());
|
||||
}
|
||||
{
|
||||
const std::string psign("+1.0");
|
||||
BOOST_CHECK(is_valid::invoke(psign.cbegin()) == psign.cend());
|
||||
const std::string nsign("-1.0");
|
||||
BOOST_CHECK(is_valid::invoke(nsign.cbegin()) == nsign.cend());
|
||||
}
|
||||
{
|
||||
const std::string psmall("+0.001");
|
||||
BOOST_CHECK(is_valid::invoke(psmall.cbegin()) == psmall.cend());
|
||||
const std::string nsmall("-0.001");
|
||||
BOOST_CHECK(is_valid::invoke(nsmall.cbegin()) == nsmall.cend());
|
||||
}
|
||||
{
|
||||
const std::string zero("0.0");
|
||||
BOOST_CHECK(is_valid::invoke(zero.cbegin()) == zero.cend());
|
||||
}
|
||||
{
|
||||
const std::string us("9_224_617.445_991_228_313");
|
||||
BOOST_CHECK(is_valid::invoke(us.cbegin()) == us.cend());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#define TOML11_ACCEPTOR
|
||||
#include <type_traits>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include "exception.hpp"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
@ -11,7 +13,7 @@ struct is_charactor
|
||||
{
|
||||
typedef charT value_type;
|
||||
constexpr static value_type target = c;
|
||||
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
@ -21,34 +23,6 @@ struct is_charactor
|
||||
}
|
||||
};
|
||||
|
||||
template<typename charT, charT head, charT ... tail>
|
||||
struct is_none_of
|
||||
{
|
||||
typedef charT value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
constexpr static Iterator invoke(Iterator iter)
|
||||
{
|
||||
return *iter == head ? iter : is_not_a<tail...>::invoke(iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename charT, charT tail>
|
||||
struct is_none_of<charT, tail>
|
||||
{
|
||||
typedef charT value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
constexpr static Iterator invoke(Iterator iter)
|
||||
{
|
||||
return *iter == tail ? iter : std::next(iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename charT, charT lw, charT up>
|
||||
struct is_in_range
|
||||
{
|
||||
@ -56,7 +30,7 @@ struct is_in_range
|
||||
constexpr static value_type upper = up;
|
||||
constexpr static value_type lower = lw;
|
||||
static_assert(lower <= upper, "lower <= upper");
|
||||
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
@ -66,10 +40,8 @@ struct is_in_range
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ... condT>
|
||||
struct is_one_of;
|
||||
template<typename headT, typename ... condT>
|
||||
struct is_one_of<headT, condT...>
|
||||
struct is_one_of
|
||||
{
|
||||
typedef typename headT::value_type value_type;
|
||||
static_assert(
|
||||
@ -100,45 +72,106 @@ struct is_one_of<tailT>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ...condT>
|
||||
struct is_chain_of;
|
||||
template<typename headT, typename ...condT>
|
||||
struct is_chain_of<headT, condT ... >
|
||||
// just a wrapper for maybe_ignored
|
||||
template<typename condT>
|
||||
struct is_ignorable
|
||||
{
|
||||
typedef typename headT::value_type value_type;
|
||||
static_assert(
|
||||
std::is_same<value_type, typename is_one_of<condT...>::value_type>::value,
|
||||
"different value_type");
|
||||
typedef typename condT::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
const Iterator tmp = headT::invoke(iter);
|
||||
return (tmp != iter) ? is_chain_of<condT...>::invoke(tmp) : iter;
|
||||
}
|
||||
};
|
||||
template<typename tailT>
|
||||
struct is_chain_of<tailT>
|
||||
{
|
||||
typedef typename tailT::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
const Iterator tmp = tailT::invoke(iter);
|
||||
const Iterator tmp = condT::invoke(iter);
|
||||
return (tmp != iter) ? tmp : iter;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename condT>
|
||||
struct maybe_ignored : std::false_type{};
|
||||
template<typename condT>
|
||||
struct maybe_ignored<is_ignorable<condT>> : std::true_type{};
|
||||
|
||||
template<typename headT, typename ... condT>
|
||||
struct is_chain_of_impl
|
||||
{
|
||||
typedef typename headT::value_type value_type;
|
||||
static_assert(std::is_same<value_type,
|
||||
typename is_chain_of_impl<condT...>::value_type>::value,
|
||||
"different value_type");
|
||||
|
||||
constexpr static bool ignorable = maybe_ignored<headT>::value;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter, Iterator rollback)
|
||||
{
|
||||
const Iterator tmp = headT::invoke(iter);
|
||||
return (tmp == iter && not ignorable) ? rollback :
|
||||
is_chain_of_impl<condT...>::invoke(tmp, rollback);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename tailT>
|
||||
struct is_chain_of_impl<tailT>
|
||||
{
|
||||
typedef typename tailT::value_type value_type;
|
||||
constexpr static bool ignorable = maybe_ignored<tailT>::value;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter, Iterator rollback)
|
||||
{
|
||||
const Iterator tmp = tailT::invoke(iter);
|
||||
return (tmp == iter) ? (ignorable ? iter : rollback) : tmp;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename headT, typename ...condT>
|
||||
struct is_chain_of
|
||||
{
|
||||
typedef typename is_chain_of_impl<headT, condT...>::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
return is_chain_of_impl<headT, condT...>::invoke(iter, iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename condT, std::size_t N>
|
||||
struct is_repeat_of
|
||||
{
|
||||
typedef typename condT::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
const Iterator rollback = iter;
|
||||
Iterator tmp;
|
||||
for(auto i=0ul; i<N; ++i)
|
||||
{
|
||||
tmp = condT::invoke(iter);
|
||||
if(tmp == iter) return rollback;
|
||||
iter = tmp;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename condT>
|
||||
struct is_repeat_of<condT,
|
||||
std::numeric_limits<typename condT::value_type>::infinity()>
|
||||
{
|
||||
typedef typename condT::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
@ -154,19 +187,356 @@ struct is_repeat_of
|
||||
}
|
||||
};
|
||||
|
||||
using is_space = is_charactor<char, ' '>;
|
||||
using is_tab = is_charactor<char, '\t'>;
|
||||
using is_number = is_in_range<char, '0', '9'>;
|
||||
using is_lowercase = is_in_range<char, 'a', 'z'>;
|
||||
using is_uppercase = is_in_range<char, 'A', 'Z'>;
|
||||
using is_alphabet = is_one_of<is_lowercase, is_uppercase>;
|
||||
using is_whitespace = is_one_of<is_space, is_tab>;
|
||||
using is_newline = is_one_of<is_charactor<char, '\n'>,
|
||||
is_chain_of<is_charactor<char, '\r'>, is_charactor<char, '\n'>>>;
|
||||
using is_barekey_component = is_one_of<is_alphabet, is_number,
|
||||
is_charactor<char, '_'>, is_charactor<char, '-'>>;
|
||||
using is_barekey = is_repeat_of<is_barekey_component>;
|
||||
template<typename headT, typename ... tailT>
|
||||
struct is_none_of
|
||||
{
|
||||
typedef typename headT::value_type value_type;
|
||||
static_assert(
|
||||
std::is_same<value_type, typename is_one_of<tailT...>::value_type>::value,
|
||||
"different value_type");
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
const Iterator tmp = headT::invoke(iter);
|
||||
return (tmp != iter) ? iter : is_none_of<tailT...>::invoke(iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename tailT>
|
||||
struct is_none_of<tailT>
|
||||
{
|
||||
typedef typename tailT::value_type value_type;
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
const Iterator tmp = tailT::invoke(iter);
|
||||
return (tmp != iter) ? iter : std::next(iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename notT, typename butT>
|
||||
struct is_not_but
|
||||
{
|
||||
typedef typename notT::value_type value_type;
|
||||
static_assert(
|
||||
std::is_same<value_type, typename butT::value_type>::value,
|
||||
"different value type");
|
||||
|
||||
template<typename Iterator, class = typename std::enable_if<
|
||||
std::is_same<typename std::iterator_traits<Iterator>::value_type,
|
||||
value_type>::value>::type>
|
||||
static Iterator invoke(Iterator iter)
|
||||
{
|
||||
return (iter != notT::invoke(iter)) ? iter : butT::invoke(iter);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename charT>
|
||||
using is_space = is_charactor<charT, ' '>;
|
||||
template<typename charT>
|
||||
using is_tab = is_charactor<charT, '\t'>;
|
||||
template<typename charT>
|
||||
using is_number = is_in_range<charT, '0', '9'>;
|
||||
template<typename charT>
|
||||
using is_lowercase = is_in_range<charT, 'a', 'z'>;
|
||||
template<typename charT>
|
||||
using is_uppercase = is_in_range<charT, 'A', 'Z'>;
|
||||
template<typename charT>
|
||||
using is_alphabet = is_one_of<is_lowercase<charT>, is_uppercase<charT>>;
|
||||
template<typename charT>
|
||||
using is_hex = is_one_of<is_number<charT>, is_in_range<charT, 'a', 'f'>,
|
||||
is_in_range<charT, 'A', 'F'>>;
|
||||
template<typename charT>
|
||||
using is_whitespace = is_one_of<is_space<charT>, is_tab<charT>>;
|
||||
template<typename charT>
|
||||
using is_newline = is_one_of<is_charactor<charT, '\n'>,
|
||||
is_chain_of<is_charactor<charT, '\r'>, is_charactor<charT, '\n'>>>;
|
||||
template<typename charT>
|
||||
using is_barekey_component = is_one_of<is_alphabet<charT>, is_number<charT>,
|
||||
is_charactor<charT, '_'>, is_charactor<charT, '-'>>;
|
||||
template<typename charT>
|
||||
using is_barekey = is_repeat_of<is_barekey_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>;
|
||||
template<typename charT>
|
||||
using is_comment =
|
||||
is_chain_of<
|
||||
is_charactor<charT, '#'>,
|
||||
is_repeat_of<is_none_of<is_newline<charT>>,
|
||||
std::numeric_limits<charT>::infinity()>,
|
||||
is_newline<charT>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_basic_inline_string_component =
|
||||
is_one_of<
|
||||
is_none_of< is_in_range<charT, '\0', '\31'>, is_charactor<charT, '\"'>,
|
||||
is_charactor<charT, '\\'>, is_newline<charT>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, '\"'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, '\\'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'b'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 't'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'n'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'f'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'r'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'u'>,
|
||||
is_repeat_of<is_hex<charT>, 4>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'U'>,
|
||||
is_repeat_of<is_hex<charT>, 8>>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_basic_inline_string =
|
||||
is_not_but<
|
||||
is_repeat_of<is_charactor<charT, '\"'>, 3>, // not multiline
|
||||
is_chain_of<
|
||||
is_charactor<charT, '\"'>,
|
||||
is_ignorable<is_repeat_of<is_basic_inline_string_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>>,
|
||||
is_charactor<charT, '\"'>
|
||||
>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_basic_multiline_string_component =
|
||||
is_one_of<
|
||||
is_none_of< is_in_range<charT, '\0', '\31'>,
|
||||
is_repeat_of<is_charactor<charT, '\"'>, 3>,
|
||||
is_charactor<charT, '\\'>>,
|
||||
is_newline<charT>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_newline<charT>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, '\"'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, '\\'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'b'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 't'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'n'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'f'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'r'>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'u'>,
|
||||
is_repeat_of<is_hex<charT>, 4>>,
|
||||
is_chain_of<is_charactor<charT, '\\'>, is_charactor<charT, 'U'>,
|
||||
is_repeat_of<is_hex<charT>, 8>>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_basic_multiline_string =
|
||||
is_chain_of<
|
||||
is_repeat_of<is_charactor<charT, '\"'>, 3>,
|
||||
is_ignorable<is_repeat_of<is_basic_multiline_string_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>>,
|
||||
is_repeat_of<is_charactor<charT, '\"'>, 3>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_literal_inline_string_component =
|
||||
is_none_of<is_in_range<charT, '\0', '\31'>, is_charactor<charT, '\''>>;
|
||||
|
||||
template<typename charT>
|
||||
using is_literal_inline_string =
|
||||
is_not_but<
|
||||
is_repeat_of<is_charactor<charT, '\''>, 3>,
|
||||
is_chain_of<
|
||||
is_charactor<charT, '\''>,
|
||||
is_ignorable<is_repeat_of<is_literal_inline_string_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>>,
|
||||
is_charactor<charT, '\''>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_literal_multiline_string_component =
|
||||
is_one_of<
|
||||
is_none_of<is_in_range<charT, '\0', '\31'>,
|
||||
is_repeat_of<is_charactor<charT, '\''>, 3>>,
|
||||
is_newline<charT>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_literal_multiline_string =
|
||||
is_chain_of<
|
||||
is_repeat_of<is_charactor<charT, '\''>, 3>,
|
||||
is_ignorable<is_repeat_of<is_literal_multiline_string_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>>,
|
||||
is_repeat_of<is_charactor<charT, '\''>, 3>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_sign = is_one_of<is_charactor<charT, '+'>, is_charactor<charT, '-'>>;
|
||||
template<typename charT>
|
||||
using is_nonzero_number = is_in_range<charT, '1', '9'>;
|
||||
|
||||
template<typename charT>
|
||||
using is_integer_component =
|
||||
is_not_but<
|
||||
is_repeat_of<is_charactor<charT, '_'>, 2>,
|
||||
is_one_of<
|
||||
is_charactor<charT, '_'>, is_number<charT>
|
||||
>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_integer =
|
||||
is_chain_of<
|
||||
is_ignorable<is_sign<charT>>,
|
||||
is_one_of<
|
||||
is_charactor<charT, '0'>,
|
||||
is_chain_of<
|
||||
is_nonzero_number<charT>,
|
||||
is_ignorable<is_repeat_of<is_integer_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>
|
||||
>
|
||||
>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_fractional_part =
|
||||
is_chain_of<
|
||||
is_charactor<charT, '.'>,
|
||||
is_repeat_of<is_integer_component<charT>,
|
||||
std::numeric_limits<charT>::infinity()>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_exponent_part =
|
||||
is_chain_of<
|
||||
is_one_of<is_charactor<charT, 'e'>, is_charactor<charT, 'E'>>,
|
||||
is_integer<charT>
|
||||
>;
|
||||
template<typename charT>
|
||||
using is_float =
|
||||
is_one_of<
|
||||
is_chain_of<
|
||||
is_integer<charT>,
|
||||
is_fractional_part<charT>,
|
||||
is_exponent_part<charT>
|
||||
>,
|
||||
is_chain_of<
|
||||
is_integer<charT>,
|
||||
is_fractional_part<charT>
|
||||
>,
|
||||
is_chain_of<
|
||||
is_integer<charT>,
|
||||
is_exponent_part<charT>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_boolean =
|
||||
is_one_of<
|
||||
is_chain_of<
|
||||
is_charactor<charT, 't'>,
|
||||
is_charactor<charT, 'r'>,
|
||||
is_charactor<charT, 'u'>,
|
||||
is_charactor<charT, 'e'>
|
||||
>,
|
||||
is_chain_of<
|
||||
is_charactor<charT, 'f'>,
|
||||
is_charactor<charT, 'a'>,
|
||||
is_charactor<charT, 'l'>,
|
||||
is_charactor<charT, 's'>,
|
||||
is_charactor<charT, 'e'>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_local_time =
|
||||
is_chain_of<
|
||||
is_repeat_of<is_number<charT>, 2>,
|
||||
is_charactor<charT, ':'>,
|
||||
is_repeat_of<is_number<charT>, 2>,
|
||||
is_charactor<charT, ':'>,
|
||||
is_repeat_of<is_number<charT>, 2>,
|
||||
is_ignorable<is_repeat_of<is_number<charT>,
|
||||
std::numeric_limits<charT>::infinity()>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_local_date =
|
||||
is_chain_of<
|
||||
is_repeat_of<is_number<charT>, 4>,
|
||||
is_charactor<charT, '-'>,
|
||||
is_repeat_of<is_number<charT>, 2>,
|
||||
is_charactor<charT, '-'>,
|
||||
is_repeat_of<is_number<charT>, 2>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_local_date_time =
|
||||
is_chain_of<
|
||||
is_local_date<charT>,
|
||||
is_charactor<charT, 'T'>,
|
||||
is_local_time<charT>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_offset =
|
||||
is_one_of<
|
||||
is_charactor<charT, 'Z'>,
|
||||
is_chain_of<
|
||||
is_sign<charT>,
|
||||
is_repeat_of<is_number<charT>, 2>,
|
||||
is_charactor<charT, ':'>,
|
||||
is_repeat_of<is_number<charT>, 2>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_offset_date_time =
|
||||
is_chain_of<
|
||||
is_local_date_time<charT>,
|
||||
is_offset<charT>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_elemental_type =
|
||||
is_one_of<
|
||||
is_basic_inline_string<charT>,
|
||||
is_basic_multiline_string<charT>,
|
||||
is_literal_inline_string<charT>,
|
||||
is_literal_multiline_string<charT>,
|
||||
is_integer<charT>,
|
||||
is_float<charT>,
|
||||
is_boolean<charT>,
|
||||
is_local_time<charT>,
|
||||
is_local_date<charT>,
|
||||
is_local_date_time<charT>,
|
||||
is_offset_date_time<charT>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_skippable_in_array =
|
||||
is_repeat_of<
|
||||
is_one_of<is_whitespace<charT>, is_newline<charT>, is_comment<charT>>,
|
||||
std::numeric_limits<charT>::infinity()
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_array_component =
|
||||
is_chain_of<
|
||||
is_ignorable<is_skippable_in_array<charT>>,
|
||||
is_elemental_type<charT>,
|
||||
is_ignorable<is_skippable_in_array<charT>>
|
||||
>;
|
||||
|
||||
template<typename charT>
|
||||
using is_array =
|
||||
is_chain_of<
|
||||
is_charactor<charT, '['>,
|
||||
is_ignorable<
|
||||
is_repeat_of<
|
||||
is_chain_of<is_array_component<charT>, is_charactor<charT, ','>>,
|
||||
std::numeric_limits<charT>::infinite()
|
||||
>
|
||||
>,
|
||||
is_ignorable<
|
||||
is_chain_of<
|
||||
is_array_component<charT>, is_ignorable<is_charactor<charT, ','>>
|
||||
>
|
||||
>,
|
||||
is_charactor<charT, ']'>
|
||||
>;
|
||||
|
||||
}//toml
|
||||
#endif// TOML11_ACCEPTOR
|
||||
|
Loading…
Reference in New Issue
Block a user