diff --git a/src/util/format.h b/src/util/format.h index 8520600bc..f27ab511a 100644 --- a/src/util/format.h +++ b/src/util/format.h @@ -208,21 +208,64 @@ format bracket(std::string const l, format const & x, std::string const r); format paren(format const & x); format wrap(format const & f1, format const & f2); +// is_iterator +template +struct is_iterator +{ + static constexpr bool value = false; +}; +template +struct is_iterator::value_type, void>::value>::type> +{ + static constexpr bool value = true; +}; + template format folddoc(InputIterator first, InputIterator last, F f) { - auto first_elem = *first; - return std::accumulate(++first, last, first_elem, f); + // InputIterator : iterator + static_assert(is_iterator::value, "folddoc takes non-iterator type arguments"); + // F : T x format -> format + static_assert(std::is_same::value_type, + format)>::type, format>::value, + "folddoc: return type of f is not format"); + if(first == last) { return format(); } + return f(*first, folddoc(first + 1, last, f)); } template format spread(InputIterator first, InputIterator last) { + static_assert(std::is_same::value_type, format>::value, + "stack takes an argument which is not a iterator containing format."); return folddoc(first, last, compose); } +inline format spread(std::initializer_list const & l) { + return spread(l.begin(), l.end()); +} template format stack(InputIterator first, InputIterator last) { + static_assert(std::is_same::value_type, format>::value, + "stack takes an argument which is not a iterator containing format."); return folddoc(first, last, above); } +inline format stack(std::initializer_list const & l) { + return stack(l.begin(), l.end()); +} template format fill(InputIterator first, InputIterator last) { + static_assert(std::is_same::value_type, format>::value, + "fill takes an argument which is not a iterator containing format."); return folddoc(first, last, wrap); } +inline format fill(std::initializer_list const & l) { + return fill(l.begin(), l.end()); +} +template +format fillwords(InputIterator first, InputIterator last) { + static_assert(std::is_same::value_type, + typename std::string>::value, + "fillwords takes an argument which is not a iterator containing std::string."); + return folddoc(first, last, [](std::string const & s, format const & r) { return wrap(format(s), r); } ); +} +inline format fillwords(std::initializer_list const & l) { + return fillwords(l.begin(), l.end()); +} }