diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0077748..9a3125e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,6 +6,7 @@ set(TEST_NAMES test_get test_value_operator test_datetime + test_acceptor ) add_definitions("-Wall -Wpedantic") diff --git a/tests/test_acceptor.cpp b/tests/test_acceptor.cpp new file mode 100644 index 0000000..a16d83c --- /dev/null +++ b/tests/test_acceptor.cpp @@ -0,0 +1,65 @@ +#define BOOST_TEST_MODULE "test_acceptor" +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +#include +#else +#define BOOST_TEST_NO_LIB +#include +#endif +#include +#include + +template +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 +inline wrapping_iterator wrap(T v) {return wrapping_iterator(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); +} diff --git a/toml/acceptor.hpp b/toml/acceptor.hpp new file mode 100644 index 0000000..d3409c4 --- /dev/null +++ b/toml/acceptor.hpp @@ -0,0 +1,172 @@ +#ifndef TOML11_ACCEPTOR +#define TOML11_ACCEPTOR +#include +#include + +namespace toml +{ + +template +struct is_charactor +{ + typedef charT value_type; + constexpr static value_type target = c; + + template::value_type, + value_type>::value>::type> + constexpr static Iterator invoke(Iterator iter) + { + return *iter == c ? std::next(iter) : iter; + } +}; + +template +struct is_none_of +{ + typedef charT value_type; + + template::value_type, + value_type>::value>::type> + constexpr static Iterator invoke(Iterator iter) + { + return *iter == head ? iter : is_not_a::invoke(iter); + } +}; + +template +struct is_none_of +{ + typedef charT value_type; + + template::value_type, + value_type>::value>::type> + constexpr static Iterator invoke(Iterator iter) + { + return *iter == tail ? iter : std::next(iter); + } +}; + +template +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::value_type, + value_type>::value>::type> + constexpr static Iterator invoke(Iterator iter) + { + return (lower <= *iter && *iter <= upper) ? std::next(iter) : iter; + } +}; + +template +struct is_one_of; +template +struct is_one_of +{ + typedef typename headT::value_type value_type; + static_assert( + std::is_same::value_type>::value, + "different value_type"); + + template::value_type, + value_type>::value>::type> + static Iterator invoke(Iterator iter) + { + const Iterator tmp = headT::invoke(iter); + return (tmp != iter) ? tmp : is_one_of::invoke(iter); + } +}; +template +struct is_one_of +{ + typedef typename tailT::value_type value_type; + + template::value_type, + value_type>::value>::type> + static Iterator invoke(Iterator iter) + { + const Iterator tmp = tailT::invoke(iter); + return (tmp != iter) ? tmp : iter; + } +}; + +template +struct is_chain_of; +template +struct is_chain_of +{ + typedef typename headT::value_type value_type; + static_assert( + std::is_same::value_type>::value, + "different value_type"); + + template::value_type, + value_type>::value>::type> + static Iterator invoke(Iterator iter) + { + const Iterator tmp = headT::invoke(iter); + return (tmp != iter) ? is_chain_of::invoke(tmp) : iter; + } +}; +template +struct is_chain_of +{ + typedef typename tailT::value_type value_type; + + template::value_type, + value_type>::value>::type> + static Iterator invoke(Iterator iter) + { + const Iterator tmp = tailT::invoke(iter); + return (tmp != iter) ? tmp : iter; + } +}; + +template +struct is_repeat_of +{ + typedef typename condT::value_type value_type; + + template::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; +using is_tab = is_charactor; +using is_number = is_in_range; +using is_lowercase = is_in_range; +using is_uppercase = is_in_range; +using is_alphabet = is_one_of; +using is_whitespace = is_one_of; +using is_newline = is_one_of, + is_chain_of, is_charactor>>; +using is_barekey_component = is_one_of, is_charactor>; +using is_barekey = is_repeat_of; + + +}//toml +#endif// TOML11_ACCEPTOR