Skip to content

Commit

Permalink
borrowed_iterator_t (custom), renamed source_last
Browse files Browse the repository at this point in the history
to `in` just like C++20 ranges copy functions.
Also renamed view/detail/core.h to misc.h and tweaked static_assert message
  • Loading branch information
OleErikPeistorpet committed Sep 29, 2023
1 parent 3ad5658 commit 102dbd4
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 28 deletions.
24 changes: 24 additions & 0 deletions auxi/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@

#include <iterator>

//! Users can define (to override __cpp_lib_ranges or to not pay for include)
#ifndef OEL_STD_RANGES
#if __cpp_lib_ranges < 201911
#define OEL_STD_RANGES 0
#else
#define OEL_STD_RANGES 1
#endif
#endif
#if OEL_STD_RANGES
#include <ranges>
#endif

#if !__has_include(<boost/config.hpp>)
#define OEL_NO_BOOST 1
Expand Down Expand Up @@ -90,6 +101,19 @@ using iterator_t = decltype( begin(std::declval<Range &>()) );
template< typename Range >
using sentinel_t = decltype( end(std::declval<Range &>()) );

//! Like std::ranges::borrowed_iterator_t, but doesn't require that Range has end()
template< typename Range >
using borrowed_iterator_t =
#if OEL_STD_RANGES
std::conditional_t<
std::is_lvalue_reference_v<Range> or std::ranges::enable_borrowed_range< std::remove_cvref_t<Range> >,
iterator_t<Range>,
std::ranges::dangling
>;
#else
iterator_t<Range>;
#endif

#if __cpp_lib_concepts < 201907
template< typename Iterator >
using iter_difference_t = typename std::iterator_traits<Iterator>::difference_type;
Expand Down
8 changes: 4 additions & 4 deletions dynarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ void erase_unstable(dynarray<T, A> & d, size_t index) { d.erase_unstable(d.begi
//!@{
// Overloads of generic functions for inserting into container (in range_algo.h)
template< typename T, typename A, typename InputRange > inline
void assign(dynarray<T, A> & dest, InputRange && source) { dest.assign(source); }
void assign(dynarray<T, A> & dest, InputRange && source) { dest.assign(static_cast<InputRange &&>(source)); }

template< typename T, typename A, typename InputRange > inline
void append(dynarray<T, A> & dest, InputRange && source) { dest.append(source); }
void append(dynarray<T, A> & dest, InputRange && source) { dest.append(static_cast<InputRange &&>(source)); }

template< typename T, typename A > inline
void append(dynarray<T, A> & dest, size_t n, const T & val) { dest.append(n, val); }
Expand Down Expand Up @@ -153,7 +153,7 @@ class dynarray
* Any elements held before the call are either assigned to or destroyed. */
template< typename InputRange >
auto assign(InputRange && source)
-> iterator_t<InputRange> { return _doAssign(oel::adl_begin(source), _detail::CountOrEnd(source)); }
-> borrowed_iterator_t<InputRange> { return _doAssign(oel::adl_begin(source), _detail::CountOrEnd(source)); }

void assign(size_type count, const T & val) { clear(); append(count, val); }

Expand All @@ -167,7 +167,7 @@ class dynarray
* where `end(source)` is not needed if `source.size()` exists. */
template< typename InputRange >
auto append(InputRange && source)
-> iterator_t<InputRange> { return _append(oel::adl_begin(source), _detail::CountOrEnd(source)); }
-> borrowed_iterator_t<InputRange> { return _append(oel::adl_begin(source), _detail::CountOrEnd(source)); }
//! Equivalent to `std::vector::insert(end(), il)`
void append(std::initializer_list<T> il) { append<>(il); }
/**
Expand Down
14 changes: 8 additions & 6 deletions range_algo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ constexpr void erase_adjacent_dup(Container & c) { _detail::Unique(c, int{});
template< typename Iterator >
struct copy_return
{
Iterator source_last;
Iterator in;
};
/**
* @brief Copies the elements in source into the range beginning at dest
Expand All @@ -61,8 +61,10 @@ struct copy_return
* (Views can be used for all functions taking a range as source) */
template< typename SizedInputRange, typename RandomAccessIter > inline
auto copy_unsafe(SizedInputRange && source, RandomAccessIter dest)
-> copy_return<decltype(begin(source))>
{ return {_detail::CopyUnsf(begin(source), _detail::Size(source), dest)}; }
-> copy_return< borrowed_iterator_t<SizedInputRange> >
{
return{ _detail::CopyUnsf(begin(source), _detail::Size(source), dest) };
}
/**
* @brief Copies the elements in source range into dest range, throws std::out_of_range if dest is smaller than source
* @return `begin(source)` incremented by the number of elements in source
Expand All @@ -71,7 +73,7 @@ auto copy_unsafe(SizedInputRange && source, RandomAccessIter dest)
* Requires that `source.size()` or `end(source) - begin(source)` is valid, and that dest models random_access_range. */
template< typename SizedInputRange, typename RandomAccessRange >
auto copy(SizedInputRange && source, RandomAccessRange && dest)
-> copy_return<decltype(begin(source))>;
-> copy_return< borrowed_iterator_t<SizedInputRange> >;
/**
* @brief Copies as many elements from source as will fit in dest
* @return true if all elements were copied, false means truncation happened
Expand Down Expand Up @@ -110,12 +112,12 @@ constexpr auto insert_range(Container & dest, ContainerIterator pos, InputRange

////////////////////////////////////////////////////////////////////////////////
//
// Only implementation
// Just implementation


template< typename SizedInputRange, typename RandomAccessRange >
auto oel::copy(SizedInputRange && src, RandomAccessRange && dest)
-> copy_return<decltype(begin(src))>
-> copy_return< borrowed_iterator_t<SizedInputRange> >
{
if (as_unsigned(_detail::Size(src)) <= as_unsigned(_detail::Size(dest)))
return oel::copy_unsafe(src, begin(dest));
Expand Down
11 changes: 11 additions & 0 deletions unit_test/dynarray_mutate_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,3 +928,14 @@ TEST_F(dynarrayTest, misc)
test.push_back(1);
}
}

#if OEL_STD_RANGES
void testDanglingReturn()
{
dynarray<int> d;
auto i0 = d.assign(dynarray<int>{});
auto i1 = d.append(dynarray<int>{});
static_assert(std::is_same_v<decltype(i0), std::ranges::dangling>);
static_assert(std::is_same_v<decltype(i1), std::ranges::dangling>);
}
#endif
4 changes: 2 additions & 2 deletions unit_test/range_algo_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ TEST(rangeTest, copy)
EXPECT_FALSE(success);

ASSERT_EQ(4, test[N]);
auto l = oel::copy(test2, test).source_last;
auto l = oel::copy(test2, test).in;
EXPECT_EQ(-7, test[N]);
EXPECT_TRUE(std::end(test2) == l);
{
std::list<std::string> li{"aa", "bb"};
std::array<std::string, 2> strDest;
auto sLast = oel::copy(view::move(li), strDest).source_last;
auto sLast = oel::copy(view::move(li), strDest).in;
EXPECT_EQ("aa", strDest[0]);
EXPECT_EQ("bb", strDest[1]);
EXPECT_TRUE(li.begin()->empty());
Expand Down
2 changes: 1 addition & 1 deletion view/counted.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "../util.h"
#include "detail/core.h"
#include "detail/misc.h"

/** @file
*/
Expand Down
12 changes: 0 additions & 12 deletions view/detail/core.h → view/detail/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@

#include "../../auxi/type_traits.h"

//! Users may define (to override __cpp_lib_ranges or to not pay for include)
#ifndef OEL_STD_RANGES
#if __cpp_lib_ranges < 201911
#define OEL_STD_RANGES 0
#else
#define OEL_STD_RANGES 1
#endif
#endif
#if OEL_STD_RANGES
#include <ranges>
#endif

namespace oel
{

Expand Down
1 change: 0 additions & 1 deletion view/move.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


#include "all.h"
#include "detail/core.h"

/** @file
*/
Expand Down
2 changes: 1 addition & 1 deletion view/subrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "../util.h" // for as_unsigned
#include "detail/core.h"
#include "detail/misc.h"

/** @file
*/
Expand Down
2 changes: 1 addition & 1 deletion view/transform_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "../util.h" // for TightPair
#include "detail/core.h"
#include "detail/misc.h"

/** @file
*/
Expand Down

0 comments on commit 102dbd4

Please sign in to comment.