Skip to content

Latest commit

 

History

History
332 lines (270 loc) · 8.62 KB

283.md

File metadata and controls

332 lines (270 loc) · 8.62 KB
Info

Example

int main() {
  auto v = ranges::views::ints | ranges::views::take(2);
  auto o = v | ranges::to<std::vector>();
  assert(std::size(o) == 2 and o[0] == 0 and o[1] == 1);
}

https://godbolt.org/z/Wq4h347WG

Puzzle

  • Can you implement to_vector which converts given range into vector using ranges/stl?
namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    // TODO
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    // TODO
}
} // test::stl

int main() {
  using boost::ut::operator ""_test;
  using boost::ut::expect;

  auto test = [](auto to_vector) {
    "ranges.to"_test = [=] {
        "view"_test = [=] {
            const auto view = ranges::views::ints | ranges::views::take(3);
            expect(std::vector{0, 1, 2} == to_vector(view));
        };

        "list"_test = [=] {
            const std::list l{1, 2, 3};
            expect(std::vector{1, 2, 3} == to_vector(l));
        };

        "string"_test = [=] {
            const std::string s = "str";
            expect(std::vector{'s', 't', 'r'} == to_vector(s));
        };
    };
  };

  test([](auto... ts) { return test::ranges::to_vector(ts...); });
  test([](auto... ts) { return test::stl::to_vector(ts...); });
}

https://godbolt.org/z/cPboh4nav

Solutions

namespace test::ranges {

[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}

}  // namespace test::ranges

namespace test::stl {

[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    using value_type =
        std::remove_cvref_t<decltype(*std::ranges::begin(range))>;
    std::vector<value_type> output{};
    if constexpr (requires { std::size(range); }) {
        output.reserve(std::size(range));
    }
    std::ranges::copy(std::ranges::begin(range), std::ranges::end(range),
                      std::back_inserter(output));
    return output;
}

}  // namespace test::stl

https://godbolt.org/z/s7aKThfos

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    auto cv = ::ranges::views::common(range);
    return std::vector(cv.begin(), cv.end());
}
}  // namespace test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    auto cv = ::std::ranges::views::common(std::move(range));
    return std::vector(cv.begin(), cv.end());
}
}  // namespace test::stl

https://godbolt.org/z/onqh7z3nz

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}
}  // namespace test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
  std::vector<std::ranges::range_value_t<decltype(range)>> ret;
  if constexpr(std::ranges::sized_range<decltype(range)>) {
    ret.reserve(std::ranges::size(range));
  }
  std::ranges::copy(range, std::back_inserter(ret));
  return ret;
}
}  // namespace test::stl

https://godbolt.org/z/d6jW731zc

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    // TODO
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    // TODO
}
} // test::stl

int main() {
  using boost::ut::operator ""_test;
  using boost::ut::expect;

  auto test = [](auto to_vector) {
    "ranges.to"_test = [=] {
        "view"_test = [=] {
            const auto view = ranges::views::ints | ranges::views::take(3);
            expect(std::vector{0, 1, 2} == to_vector(view));
        };

        "list"_test = [=] {
            const std::list l{1, 2, 3};
            expect(std::vector{1, 2, 3} == to_vector(l));
        };

        "string"_test = [=] {
            const std::string s = "str";
            expect(std::vector{'s', 't', 'r'} == to_vector(s));
        };
    };
  };

  test([](auto... ts) { return test::ranges::to_vector(ts...); });
  test([](auto... ts) { return test::stl::to_vector(ts...); });
}

https://godbolt.org/z/cPboh4nav

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
  return ::ranges::to<std::vector>(std::move(range));
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
  auto v = std::vector<std::ranges::range_value_t<decltype(range)>>{};
  v.reserve(std::ranges::distance(std::ranges::begin(range), std::ranges::end(range)));
  std::ranges::copy(std::ranges::begin(range), std::ranges::end(range), std::back_inserter(v));
  return v;
}
} // test::stl

https://godbolt.org/z/E4ns1M7dr

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return ::ranges::to<std::vector>(range);
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    std::vector<std::ranges::range_value_t<decltype(range)>> output{};
    output.reserve(std::ranges::size(range));
    std::ranges::copy(range.begin(), range.end(), std::back_inserter(output));
    return output;
}
} // test::stl

https://godbolt.org/z/vvPKex7r9

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return std::move(range) | ::ranges::to<std::vector>();
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    auto vec = std::vector<std::ranges::range_value_t<decltype(range)>>{};
    vec.reserve(std::ranges::size(range));
    std::ranges::move(range, std::back_inserter(vec));
    return vec;
}
} // test::stl

https://godbolt.org/z/eKaejMz3r

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}
} // test::stl

https://godbolt.org/z/jKT3c7Y8K

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    std::vector<std::ranges::range_value_t<decltype(range)>> vec{};
    vec.reserve(std::ranges::size(range));
    std::ranges::copy(std::ranges::begin(range), std::ranges::end(range), std::back_inserter(vec));
    return vec;
}
} // test::stl

https://godbolt.org/z/aaGdM1x7M

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return range | ::ranges::to<std::vector>();
}
} // test::ranges

namespace test::stl {
template <::std::ranges::range R>
[[nodiscard]] constexpr auto to_vector(R range) {
    auto vec = std::vector<std::ranges::range_value_t<R>>{};
    std::ranges::copy(range, std::back_inserter(vec));
    return vec;
}
} // test::stl

https://godbolt.org/z/5fovezv5W

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    std::vector<std::ranges::range_value_t<decltype(range)>> v;
    std::ranges::copy(range, std::back_inserter(v));
    return v;
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    using iT = std::ranges::iterator_t<decltype(range)>;
    using T = std::ranges::range_value_t<decltype(range)>;
    std::vector<T> v;
    for(iT iE = range.begin(); iE !=range.end(); iE++)
        v.push_back(*iE);
    return v;
}
} // test::stl

https://godbolt.org/z/P18j1q64h

namespace test::ranges {
[[nodiscard]] constexpr auto to_vector(std::ranges::range auto range) {
    return ::ranges::to<std::vector>(range);
}
} // test::ranges

namespace test::stl {
[[nodiscard]] constexpr auto to_vector(::std::ranges::range auto range) {
    std::vector<std::ranges::range_value_t<decltype(range)>> v;
    if constexpr(std::ranges::sized_range<decltype(range)>) {
        v.reserve(std::ranges::size(range));
    }
    std::ranges::copy(range, std::back_inserter(v));
    return v;
}
} // test::stl

https://godbolt.org/z/6Mvv4fzPo