mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 19:10:11 +08:00
add simple acceptors
This commit is contained in:
@@ -6,6 +6,7 @@ set(TEST_NAMES
|
|||||||
test_get
|
test_get
|
||||||
test_value_operator
|
test_value_operator
|
||||||
test_datetime
|
test_datetime
|
||||||
|
test_acceptor
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions("-Wall -Wpedantic")
|
add_definitions("-Wall -Wpedantic")
|
||||||
|
65
tests/test_acceptor.cpp
Normal file
65
tests/test_acceptor.cpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_acceptor"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml/acceptor.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct wrapping_iterator
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef std::size_t difference_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
wrapping_iterator(value_type v) : value_(v){}
|
||||||
|
|
||||||
|
value_type operator*(){return value_;}
|
||||||
|
|
||||||
|
wrapping_iterator operator++() {advanced = true;return *this;}
|
||||||
|
wrapping_iterator operator++(int){advanced = true;return *this;}
|
||||||
|
|
||||||
|
operator bool() const {return advanced;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool advanced = false;
|
||||||
|
value_type value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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_tab::invoke(wrap('\t')));
|
||||||
|
BOOST_CHECK(!toml::is_tab::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')));
|
||||||
|
|
||||||
|
for(char c = 'a'; c <= 'z'; ++c)
|
||||||
|
BOOST_CHECK(toml::is_lowercase::invoke(wrap(c)));
|
||||||
|
BOOST_CHECK(!toml::is_lowercase::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_whitespace::invoke(wrap(' ')));
|
||||||
|
BOOST_CHECK(toml::is_whitespace::invoke(wrap('\t')));
|
||||||
|
|
||||||
|
std::string barekey("hoge1-piyo2_fuga3");
|
||||||
|
BOOST_CHECK(toml::is_barekey::invoke(barekey.cbegin()) == barekey.cend());
|
||||||
|
std::string partial("hoge1.piyo2_fuga3");
|
||||||
|
BOOST_CHECK(toml::is_barekey::invoke(partial.cbegin()) == partial.cbegin()+5);
|
||||||
|
}
|
172
toml/acceptor.hpp
Normal file
172
toml/acceptor.hpp
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#ifndef TOML11_ACCEPTOR
|
||||||
|
#define TOML11_ACCEPTOR
|
||||||
|
#include <type_traits>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename charT, charT c>
|
||||||
|
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>
|
||||||
|
constexpr static Iterator invoke(Iterator iter)
|
||||||
|
{
|
||||||
|
return *iter == c ? std::next(iter) : iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
typedef charT value_type;
|
||||||
|
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>
|
||||||
|
constexpr static Iterator invoke(Iterator iter)
|
||||||
|
{
|
||||||
|
return (lower <= *iter && *iter <= upper) ? std::next(iter) : iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ... condT>
|
||||||
|
struct is_one_of;
|
||||||
|
template<typename headT, typename ... condT>
|
||||||
|
struct is_one_of<headT, condT...>
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
|
||||||
|
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) ? tmp : is_one_of<condT...>::invoke(iter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename tailT>
|
||||||
|
struct is_one_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) ? tmp : iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ...condT>
|
||||||
|
struct is_chain_of;
|
||||||
|
template<typename headT, typename ...condT>
|
||||||
|
struct is_chain_of<headT, condT ... >
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
|
||||||
|
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);
|
||||||
|
return (tmp != iter) ? tmp : iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename condT>
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Iterator tmp = condT::invoke(iter);
|
||||||
|
while(tmp != iter)
|
||||||
|
{
|
||||||
|
iter = tmp;
|
||||||
|
tmp = condT::invoke(iter);
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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>;
|
||||||
|
|
||||||
|
|
||||||
|
}//toml
|
||||||
|
#endif// TOML11_ACCEPTOR
|
Reference in New Issue
Block a user