-template <
- class Collection,
- class T = typename std::remove_pointer<
- decltype(std::declval<Collection>().data())>::type>
-constexpr Range<T*> range(Collection&& v) {
- return Range<T*>(v.data(), v.data() + v.size());
+template <class Collection>
+constexpr auto range(Collection& v) -> Range<decltype(v.data())> {
+ return Range<decltype(v.data())>(v.data(), v.data() + v.size());
+}
+template <class Collection>
+constexpr auto range(Collection const& v) -> Range<decltype(v.data())> {
+ return Range<decltype(v.data())>(v.data(), v.data() + v.size());
+}
+template <class Collection>
+constexpr auto crange(Collection const& v) -> Range<decltype(v.data())> {
+ return Range<decltype(v.data())>(v.data(), v.data() + v.size());