summaryrefslogtreecommitdiffstats
path: root/src/third-party/scnlib/include/scn/detail/vectored.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/third-party/scnlib/include/scn/detail/vectored.h')
-rw-r--r--src/third-party/scnlib/include/scn/detail/vectored.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/third-party/scnlib/include/scn/detail/vectored.h b/src/third-party/scnlib/include/scn/detail/vectored.h
new file mode 100644
index 0000000..f5c3868
--- /dev/null
+++ b/src/third-party/scnlib/include/scn/detail/vectored.h
@@ -0,0 +1,166 @@
+// Copyright 2017 Elias Kosunen
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file is a part of scnlib:
+// https://github.com/eliaskosunen/scnlib
+
+#ifndef SCN_DETAIL_VECTORED_H
+#define SCN_DETAIL_VECTORED_H
+
+#include "../ranges/util.h"
+#include "../util/math.h"
+
+namespace scn {
+ SCN_BEGIN_NAMESPACE
+
+ namespace detail {
+ namespace _get_buffer {
+ struct fn {
+ private:
+ template <typename It>
+ static It _get_end(It begin, It end, size_t max_size)
+ {
+ return begin +
+ min(max_size, static_cast<std::size_t>(
+ ranges::distance(begin, end)));
+ }
+
+ template <typename CharT>
+ static SCN_CONSTEXPR14
+ span<typename std::add_const<CharT>::type>
+ impl(span<span<CharT>> s,
+ typename span<CharT>::iterator begin,
+ size_t max_size,
+ priority_tag<3>) noexcept
+ {
+ auto buf_it = s.begin();
+ for (; buf_it != s.end(); ++buf_it) {
+ if (begin >= buf_it->begin() && begin < buf_it->end()) {
+ break;
+ }
+ if (begin == buf_it->end()) {
+ ++buf_it;
+ begin = buf_it->begin();
+ break;
+ }
+ }
+ if (buf_it == s.end()) {
+ return {};
+ }
+ return {begin, _get_end(begin, buf_it->end(), max_size)};
+ }
+
+ template <
+ typename Range,
+ typename std::enable_if<SCN_CHECK_CONCEPT(
+ ranges::contiguous_range<Range>)>::type* = nullptr>
+ static SCN_CONSTEXPR14 span<typename std::add_const<
+ ranges::range_value_t<const Range>>::type>
+ impl(const Range& s,
+ ranges::iterator_t<const Range> begin,
+ size_t max_size,
+ priority_tag<2>) noexcept
+ {
+ auto b = ranges::begin(s);
+ auto e = ranges::end(s);
+ return {to_address(begin),
+ _get_end(to_address(begin),
+ to_address_safe(e, b, e), max_size)};
+ }
+
+ template <typename Range, typename It>
+ static auto impl(
+ const Range& r,
+ It begin,
+ size_t max_size,
+ priority_tag<1>) noexcept(noexcept(r.get_buffer(begin,
+ max_size)))
+ -> decltype(r.get_buffer(begin, max_size))
+ {
+ return r.get_buffer(begin, max_size);
+ }
+
+ template <typename Range, typename It>
+ static auto impl(
+ const Range& r,
+ It begin,
+ size_t max_size,
+ priority_tag<0>) noexcept(noexcept(get_buffer(r,
+ begin,
+ max_size)))
+ -> decltype(get_buffer(r, begin, max_size))
+ {
+ return get_buffer(r, begin, max_size);
+ }
+
+ public:
+ template <typename Range, typename It>
+ SCN_CONSTEXPR14 auto operator()(const Range& r,
+ It begin,
+ size_t max_size) const
+ noexcept(noexcept(
+ fn::impl(r, begin, max_size, priority_tag<3>{})))
+ -> decltype(fn::impl(r,
+ begin,
+ max_size,
+ priority_tag<3>{}))
+ {
+ return fn::impl(r, begin, max_size, priority_tag<3>{});
+ }
+
+ template <typename Range, typename It>
+ SCN_CONSTEXPR14 auto operator()(const Range& r, It begin) const
+ noexcept(
+ noexcept(fn::impl(r,
+ begin,
+ std::numeric_limits<size_t>::max(),
+ priority_tag<3>{})))
+ -> decltype(fn::impl(r,
+ begin,
+ std::numeric_limits<size_t>::max(),
+ priority_tag<3>{}))
+ {
+ return fn::impl(r, begin,
+ std::numeric_limits<size_t>::max(),
+ priority_tag<3>{});
+ }
+ };
+ } // namespace _get_buffer
+
+ namespace {
+ static constexpr auto& get_buffer =
+ detail::static_const<_get_buffer::fn>::value;
+ } // namespace
+
+ struct provides_buffer_access_concept {
+ template <typename Range, typename Iterator>
+ auto _test_requires(const Range& r, Iterator begin)
+ -> decltype(scn::detail::valid_expr(
+ ::scn::detail::get_buffer(r, begin)));
+ };
+ template <typename Range, typename = void>
+ struct provides_buffer_access_impl
+ : std::integral_constant<
+ bool,
+ ::scn::custom_ranges::detail::_requires<
+ provides_buffer_access_concept,
+ Range,
+ ::scn::ranges::iterator_t<const Range>>::value> {
+ };
+ } // namespace detail
+
+ SCN_END_NAMESPACE
+} // namespace scn
+
+#endif