refactor: remove template from detail::region

This commit is contained in:
ToruNiina 2020-07-25 22:01:34 +09:00
parent 72f5afb6af
commit 19cc9a2edf
4 changed files with 78 additions and 94 deletions

View File

@ -58,7 +58,7 @@ struct character
{
static constexpr char target = C;
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
if(loc.iter() == loc.end()) {return none();}
@ -71,7 +71,7 @@ struct character
}
loc.advance(); // update location
return ok(region<std::vector<char>>(loc, first, loc.iter()));
return ok(region(loc, first, loc.iter()));
}
};
template<char C>
@ -87,7 +87,7 @@ struct in_range
static constexpr char upper = Up;
static constexpr char lower = Low;
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
if(loc.iter() == loc.end()) {return none();}
@ -100,7 +100,7 @@ struct in_range
}
loc.advance();
return ok(region<std::vector<char>>(loc, first, loc.iter()));
return ok(region(loc, first, loc.iter()));
}
};
template<char L, char U> constexpr char in_range<L, U>::upper;
@ -111,7 +111,7 @@ template<char L, char U> constexpr char in_range<L, U>::lower;
template<typename Combinator>
struct exclude
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
if(loc.iter() == loc.end()) {return none();}
@ -124,7 +124,7 @@ struct exclude
return none();
}
loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
return ok(region<std::vector<char>>(loc, first, loc.iter()));
return ok(region(loc, first, loc.iter()));
}
};
@ -132,7 +132,7 @@ struct exclude
template<typename Combinator>
struct maybe
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
const auto rslt = Combinator::invoke(loc);
@ -140,7 +140,7 @@ struct maybe
{
return rslt;
}
return ok(region<std::vector<char>>(loc));
return ok(region(loc));
}
};
@ -150,7 +150,7 @@ struct sequence;
template<typename Head, typename ... Tail>
struct sequence<Head, Tail...>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
const auto first = loc.iter();
@ -165,8 +165,8 @@ struct sequence<Head, Tail...>
// called from the above function only, recursively.
template<typename Iterator>
static result<region<std::vector<char>>, none_t>
invoke(location& loc, region<std::vector<char>> reg, Iterator first)
static result<region, none_t>
invoke(location& loc, region reg, Iterator first)
{
const auto rslt = Head::invoke(loc);
if(rslt.is_err())
@ -184,8 +184,8 @@ struct sequence<Head>
{
// would be called from sequence<T ...>::invoke only.
template<typename Iterator>
static result<region<std::vector<char>>, none_t>
invoke(location& loc, region<std::vector<char>> reg, Iterator first)
static result<region, none_t>
invoke(location& loc, region reg, Iterator first)
{
const auto rslt = Head::invoke(loc);
if(rslt.is_err())
@ -204,7 +204,7 @@ struct either;
template<typename Head, typename ... Tail>
struct either<Head, Tail...>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
const auto rslt = Head::invoke(loc);
@ -215,7 +215,7 @@ struct either<Head, Tail...>
template<typename Head>
struct either<Head>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
return Head::invoke(loc);
@ -232,10 +232,10 @@ struct unlimited{};
template<typename T, std::size_t N>
struct repeat<T, exactly<N>>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
region<std::vector<char>> retval(loc);
region retval(loc);
const auto first = loc.iter();
for(std::size_t i=0; i<N; ++i)
{
@ -254,10 +254,10 @@ struct repeat<T, exactly<N>>
template<typename T, std::size_t N>
struct repeat<T, at_least<N>>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
region<std::vector<char>> retval(loc);
region retval(loc);
const auto first = loc.iter();
for(std::size_t i=0; i<N; ++i)
@ -285,10 +285,10 @@ struct repeat<T, at_least<N>>
template<typename T>
struct repeat<T, unlimited>
{
static result<region<std::vector<char>>, none_t>
static result<region, none_t>
invoke(location& loc)
{
region<std::vector<char>> retval(loc);
region retval(loc);
while(true)
{
auto rslt = T::invoke(loc);

View File

@ -25,7 +25,7 @@ namespace toml
namespace detail
{
inline result<std::pair<boolean, region<std::vector<char>>>, std::string>
inline result<std::pair<boolean, region>, std::string>
parse_boolean(location& loc)
{
const auto first = loc.iter();
@ -47,7 +47,7 @@ parse_boolean(location& loc)
{{std::addressof(loc), "the next token is not a boolean"}}));
}
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
inline result<std::pair<integer, region>, std::string>
parse_binary_integer(location& loc)
{
const auto first = loc.iter();
@ -76,7 +76,7 @@ parse_binary_integer(location& loc)
{{std::addressof(loc), "the next token is not an integer"}}));
}
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
inline result<std::pair<integer, region>, std::string>
parse_octal_integer(location& loc)
{
const auto first = loc.iter();
@ -96,7 +96,7 @@ parse_octal_integer(location& loc)
{{std::addressof(loc), "the next token is not an integer"}}));
}
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
inline result<std::pair<integer, region>, std::string>
parse_hexadecimal_integer(location& loc)
{
const auto first = loc.iter();
@ -116,7 +116,7 @@ parse_hexadecimal_integer(location& loc)
{{std::addressof(loc), "the next token is not an integer"}}));
}
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
inline result<std::pair<integer, region>, std::string>
parse_integer(location& loc)
{
const auto first = loc.iter();
@ -125,7 +125,7 @@ parse_integer(location& loc)
const auto second = std::next(first);
if(second == loc.end()) // the token is just zero.
{
return ok(std::make_pair(0, region<std::vector<char>>(loc, first, second)));
return ok(std::make_pair(0, region(loc, first, second)));
}
if(*second == 'b') {return parse_binary_integer (loc);} // 0b1100
@ -161,7 +161,7 @@ parse_integer(location& loc)
{{std::addressof(loc), "the next token is not an integer"}}));
}
inline result<std::pair<floating, region<std::vector<char>>>, std::string>
inline result<std::pair<floating, region>, std::string>
parse_floating(location& loc)
{
const auto first = loc.iter();
@ -249,9 +249,7 @@ parse_floating(location& loc)
{{std::addressof(loc), "the next token is not a float"}}));
}
template<typename Container>
std::string read_utf8_codepoint(const region<Container>& reg,
/* for err msg */ const location& loc)
inline std::string read_utf8_codepoint(const region& reg, const location& loc)
{
const auto str = reg.str().substr(1);
std::uint_least32_t codepoint;
@ -363,7 +361,7 @@ inline result<std::string, std::string> parse_escape_sequence(location& loc)
return err(msg);
}
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
inline result<std::pair<toml::string, region>, std::string>
parse_ml_basic_string(location& loc)
{
const auto first = loc.iter();
@ -442,7 +440,7 @@ parse_ml_basic_string(location& loc)
}
}
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
inline result<std::pair<toml::string, region>, std::string>
parse_basic_string(location& loc)
{
const auto first = loc.iter();
@ -494,7 +492,7 @@ parse_basic_string(location& loc)
}
}
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
inline result<std::pair<toml::string, region>, std::string>
parse_ml_literal_string(location& loc)
{
const auto first = loc.iter();
@ -556,7 +554,7 @@ parse_ml_literal_string(location& loc)
}
}
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
inline result<std::pair<toml::string, region>, std::string>
parse_literal_string(location& loc)
{
const auto first = loc.iter();
@ -596,7 +594,7 @@ parse_literal_string(location& loc)
}
}
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
inline result<std::pair<toml::string, region>, std::string>
parse_string(location& loc)
{
if(loc.iter() != loc.end() && *(loc.iter()) == '"')
@ -627,7 +625,7 @@ parse_string(location& loc)
{{std::addressof(loc), "the next token is not a string"}}));
}
inline result<std::pair<local_date, region<std::vector<char>>>, std::string>
inline result<std::pair<local_date, region>, std::string>
parse_local_date(location& loc)
{
const auto first = loc.iter();
@ -676,7 +674,7 @@ parse_local_date(location& loc)
}
}
inline result<std::pair<local_time, region<std::vector<char>>>, std::string>
inline result<std::pair<local_time, region>, std::string>
parse_local_time(location& loc)
{
const auto first = loc.iter();
@ -764,7 +762,7 @@ parse_local_time(location& loc)
}
}
inline result<std::pair<local_datetime, region<std::vector<char>>>, std::string>
inline result<std::pair<local_datetime, region>, std::string>
parse_local_datetime(location& loc)
{
const auto first = loc.iter();
@ -808,7 +806,7 @@ parse_local_datetime(location& loc)
}
}
inline result<std::pair<offset_datetime, region<std::vector<char>>>, std::string>
inline result<std::pair<offset_datetime, region>, std::string>
parse_offset_datetime(location& loc)
{
const auto first = loc.iter();
@ -856,7 +854,7 @@ parse_offset_datetime(location& loc)
}
}
inline result<std::pair<key, region<std::vector<char>>>, std::string>
inline result<std::pair<key, region>, std::string>
parse_simple_key(location& loc)
{
if(const auto bstr = parse_basic_string(loc))
@ -877,7 +875,7 @@ parse_simple_key(location& loc)
}
// dotted key become vector of keys
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
inline result<std::pair<std::vector<key>, region>, std::string>
parse_key(location& loc)
{
const auto first = loc.iter();
@ -939,7 +937,7 @@ template<typename Value>
result<Value, std::string> parse_value(location&);
template<typename Value>
result<std::pair<typename Value::array_type, region<std::vector<char>>>, std::string>
result<std::pair<typename Value::array_type, region>, std::string>
parse_array(location& loc)
{
using value_type = Value;
@ -968,7 +966,7 @@ parse_array(location& loc)
{
loc.advance(); // skip ']'
return ok(std::make_pair(retval,
region<std::vector<char>>(loc, first, loc.iter())));
region(loc, first, loc.iter())));
}
if(auto val = parse_value<value_type>(loc))
@ -1021,7 +1019,7 @@ parse_array(location& loc)
{
loc.advance(); // skip ']'
return ok(std::make_pair(retval,
region<std::vector<char>>(loc, first, loc.iter())));
region(loc, first, loc.iter())));
}
else
{
@ -1044,7 +1042,7 @@ parse_array(location& loc)
}
template<typename Value>
result<std::pair<std::pair<std::vector<key>, region<std::vector<char>>>, Value>, std::string>
result<std::pair<std::pair<std::vector<key>, region>, Value>, std::string>
parse_key_value_pair(location& loc)
{
using value_type = Value;
@ -1133,7 +1131,7 @@ std::string format_dotted_keys(InputIterator first, const InputIterator last)
}
// forward decl for is_valid_forward_table_definition
result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
result<std::pair<std::vector<key>, region>, std::string>
parse_table_key(location& loc);
// The following toml file is allowed.
@ -1205,7 +1203,7 @@ template<typename Value, typename InputIterator>
result<bool, std::string>
insert_nested_key(typename Value::table_type& root, const Value& v,
InputIterator iter, const InputIterator last,
region<std::vector<char>> key_reg,
region key_reg,
const bool is_array_of_table = false)
{
static_assert(std::is_same<key,
@ -1439,7 +1437,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
}
template<typename Value>
result<std::pair<typename Value::table_type, region<std::vector<char>>>, std::string>
result<std::pair<typename Value::table_type, region>, std::string>
parse_inline_table(location& loc)
{
using value_type = Value;
@ -1461,7 +1459,7 @@ parse_inline_table(location& loc)
{
loc.advance(); // skip `}`
return ok(std::make_pair(retval,
region<std::vector<char>>(loc, first, loc.iter())));
region(loc, first, loc.iter())));
}
const auto kv_r = parse_key_value_pair<value_type>(loc);
@ -1492,7 +1490,7 @@ parse_inline_table(location& loc)
{
loc.advance(); // skip `}`
return ok(std::make_pair(
retval, region<std::vector<char>>(loc, first, loc.iter())));
retval, region(loc, first, loc.iter())));
}
else if(*loc.iter() == '#' || *loc.iter() == '\r' || *loc.iter() == '\n')
{
@ -1709,7 +1707,7 @@ result<Value, std::string> parse_value(location& loc)
}
}
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
inline result<std::pair<std::vector<key>, region>, std::string>
parse_table_key(location& loc)
{
if(auto token = lex_std_table::invoke(loc))
@ -1770,7 +1768,7 @@ parse_table_key(location& loc)
}
}
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
inline result<std::pair<std::vector<key>, region>, std::string>
parse_array_table_key(location& loc)
{
if(auto token = lex_array_table::invoke(loc))
@ -1927,7 +1925,7 @@ result<Value, std::string> parse_toml_file(location& loc)
// put the first line as a region of a file
// Here first != loc.end(), so taking std::next is okay
const region<std::vector<char>> file(loc, first, std::next(loc.iter()));
const region file(loc, first, std::next(loc.iter()));
// The first successive comments that are separated from the first value
// by an empty line are for a file itself.

View File

@ -194,16 +194,10 @@ struct location final : public region_base
//
// it contains pointer to the file content and iterator that points the first
// and last location.
template<typename Container>
struct region final : public region_base
{
using const_iterator = typename Container::const_iterator;
using source_ptr = std::shared_ptr<const Container>;
static_assert(std::is_same<char, typename Container::value_type>::value,"");
static_assert(std::is_same<std::random_access_iterator_tag,
typename std::iterator_traits<const_iterator>::iterator_category>::value,
"container should be randomly accessible");
using const_iterator = typename std::vector<char>::const_iterator;
using source_ptr = std::shared_ptr<const std::vector<char>>;
// delete default constructor. source_ never be null.
region() = delete;

View File

@ -1056,95 +1056,87 @@ class basic_value
//
// Those constructors take detail::region that contains parse result.
template<typename Container>
basic_value(boolean b, detail::region<Container> reg)
basic_value(boolean b, detail::region reg)
: type_(value_t::boolean),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->boolean_, b);
}
template<typename T, typename Container, typename std::enable_if<
template<typename T, typename std::enable_if<
detail::conjunction<
std::is_integral<T>, detail::negation<std::is_same<T, boolean>>
>::value, std::nullptr_t>::type = nullptr>
basic_value(T i, detail::region<Container> reg)
basic_value(T i, detail::region reg)
: type_(value_t::integer),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->integer_, static_cast<integer>(i));
}
template<typename T, typename Container, typename std::enable_if<
template<typename T, typename std::enable_if<
std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr>
basic_value(T f, detail::region<Container> reg)
basic_value(T f, detail::region reg)
: type_(value_t::floating),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->floating_, static_cast<floating>(f));
}
template<typename Container>
basic_value(toml::string s, detail::region<Container> reg)
basic_value(toml::string s, detail::region reg)
: type_(value_t::string),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->string_, std::move(s));
}
template<typename Container>
basic_value(const local_date& ld, detail::region<Container> reg)
basic_value(const local_date& ld, detail::region reg)
: type_(value_t::local_date),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->local_date_, ld);
}
template<typename Container>
basic_value(const local_time& lt, detail::region<Container> reg)
basic_value(const local_time& lt, detail::region reg)
: type_(value_t::local_time),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->local_time_, lt);
}
template<typename Container>
basic_value(const local_datetime& ldt, detail::region<Container> reg)
basic_value(const local_datetime& ldt, detail::region reg)
: type_(value_t::local_datetime),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->local_datetime_, ldt);
}
template<typename Container>
basic_value(const offset_datetime& odt, detail::region<Container> reg)
basic_value(const offset_datetime& odt, detail::region reg)
: type_(value_t::offset_datetime),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->offset_datetime_, odt);
}
template<typename Container>
basic_value(const array_type& ary, detail::region<Container> reg)
basic_value(const array_type& ary, detail::region reg)
: type_(value_t::array),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->array_, ary);
}
template<typename Container>
basic_value(const table_type& tab, detail::region<Container> reg)
basic_value(const table_type& tab, detail::region reg)
: type_(value_t::table),
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
region_info_(std::make_shared<detail::region>(std::move(reg))),
comments_(region_info_->comments())
{
assigner(this->table_, tab);
}
template<typename T, typename Container, typename std::enable_if<
template<typename T, typename std::enable_if<
detail::is_exact_toml_type<T, value_type>::value,
std::nullptr_t>::type = nullptr>
basic_value(std::pair<T, detail::region<Container>> parse_result)
basic_value(std::pair<T, detail::region> parse_result)
: basic_value(std::move(parse_result.first), std::move(parse_result.second))
{}