Skip to content

Commit

Permalink
Merge pull request #674 from CaseyCarter/optional
Browse files Browse the repository at this point in the history
Implement optional per C++17 + P0602
  • Loading branch information
ericniebler committed Jun 21, 2017
2 parents 136b6ba + 900e381 commit 3a074ed
Show file tree
Hide file tree
Showing 22 changed files with 1,157 additions and 342 deletions.
2 changes: 1 addition & 1 deletion Version.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# This makefile will generate a new version.hpp, *AMEND THE MOST RECENT COMMIT*, and git-tag the commit.
set(RANGE_V3_MAJOR 0)
set(RANGE_V3_MINOR 2)
set(RANGE_V3_PATCHLEVEL 5)
set(RANGE_V3_PATCHLEVEL 6)
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class Rangev3Conan(ConanFile):
name = "range-v3"
version = "0.2.5"
version = "0.2.6"
license = "Boost Software License - Version 1.0 - August 17th, 2003"
url = "https://github.com/ericniebler/range-v3"
exports = "*"
Expand Down
173 changes: 0 additions & 173 deletions include/range/v3/detail/optional.hpp

This file was deleted.

92 changes: 16 additions & 76 deletions include/range/v3/experimental/utility/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
#include <meta/meta.hpp>
#include <range/v3/range_traits.hpp>
#include <range/v3/view_facade.hpp>
#include <range/v3/detail/optional.hpp>
#include <range/v3/utility/box.hpp>
#include <range/v3/utility/concepts.hpp>
#include <range/v3/utility/semiregular.hpp>
#include <range/v3/utility/swap.hpp>
#include <range/v3/view/all.hpp>

Expand Down Expand Up @@ -116,83 +116,14 @@ namespace ranges
/// \cond
namespace detail
{
// storage for the reference to the current element
template<typename Reference, typename = void>
struct generator_promise_storage
{
CONCEPT_ASSERT(CopyConstructible<Reference>());

Reference const &read() const noexcept
{
RANGES_EXPECT(opt_);
return *opt_;
}
template<typename Arg,
CONCEPT_REQUIRES_(Assignable<Reference &, Arg>())>
void store(Arg &&arg)
{
// ranges::optional is weird. For std::optional this would be:
// opt_ = std::forward<Arg>(arg);
if (opt_) *opt_ = std::forward<Arg>(arg);
else opt_ = std::forward<Arg>(arg);
}
template<typename Arg,
CONCEPT_REQUIRES_(!Assignable<Reference &, Arg>() &&
Constructible<Reference, Arg>())>
void store(Arg &&arg)
{
// ranges::optional is weird. For std::optional this would be:
// opt_.emplace(std::forward<Arg>(arg));
opt_ = std::forward<Arg>(arg);
}
private:
optional<Reference> opt_;
};

template<typename Reference>
struct generator_promise_storage<Reference, meta::if_<std::is_reference<Reference>>>
{
Reference read() const noexcept
{
RANGES_EXPECT(ptr_);
return static_cast<Reference>(*ptr_);
}
template<typename Arg>
void store(Arg &&arg) noexcept
{
ptr_ = std::addressof(arg);
}
private:
meta::_t<std::remove_reference<Reference>> *ptr_ = nullptr;
};

template<typename Reference>
struct generator_promise_storage<Reference, meta::if_<SemiRegular<Reference>>>
: private box<Reference, generator_promise_storage<Reference>>
{
Reference const &read() const noexcept
{
return get();
}
template<typename Arg>
void store(Arg &&arg)
{
get() = std::forward<Arg>(arg);
}
private:
using box<Reference, generator_promise_storage<Reference>>::get;
};

template<typename Reference>
struct generator_promise
: private generator_promise_storage<Reference>
{
private:
using base_t = generator_promise_storage<Reference>;
public:
std::exception_ptr except_ = nullptr;

using base_t::read;
CONCEPT_ASSERT(meta::or_<std::is_reference<Reference>,
CopyConstructible<Reference>>());

generator_promise *get_return_object() noexcept
{
return this;
Expand All @@ -212,11 +143,13 @@ namespace ranges
except_ = std::current_exception();
RANGES_EXPECT(except_);
}
template<typename Arg, CONCEPT_REQUIRES_(ConvertibleTo<Arg, Reference>())>
template<typename Arg,
CONCEPT_REQUIRES_(ConvertibleTo<Arg, Reference>() &&
std::is_assignable<semiregular_t<Reference> &, Arg>::value)>
std::experimental::suspend_always yield_value(Arg &&arg)
noexcept(noexcept(std::declval<base_t &>().store(std::declval<Arg>())))
noexcept(std::is_nothrow_assignable<semiregular_t<Reference> &, Arg>::value)
{
base_t::store(std::forward<Arg>(arg));
ref_ = std::forward<Arg>(arg);
return {};
}
std::experimental::suspend_never
Expand All @@ -225,6 +158,13 @@ namespace ranges
RANGES_ENSURE_MSG(false, "Invalid size request for a non-sized generator");
return {};
}
meta::if_<std::is_reference<Reference>, Reference, Reference const &>
read() const noexcept
{
return ref_;
}
private:
semiregular_t<Reference> ref_;
};

template<typename Reference>
Expand Down
9 changes: 1 addition & 8 deletions include/range/v3/istream_range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,10 @@ namespace ranges
{
return cursor{*this};
}

istream_range(std::istream &sin, Val *)
: sin_(&sin), obj_{}
{}
istream_range(std::istream &sin, semiregular<Val> *)
: sin_(&sin), obj_{in_place}
{}
public:
istream_range() = default;
istream_range(std::istream &sin)
: istream_range(sin, _nullptr_v<semiregular_t<Val>>())
: sin_(&sin), obj_{}
{
next(); // prime the pump
}
Expand Down
47 changes: 38 additions & 9 deletions include/range/v3/range_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,23 +268,52 @@ namespace ranges
{};

#if defined(__clang__) && !defined(_LIBCPP_VERSION)
template<typename T, typename Arg = T>
struct is_trivially_copy_assignable
: meta::bool_<__is_trivially_assignable(T &, Arg const&)>
{};
template<typename T, typename Arg = T>
struct is_trivially_move_assignable
: meta::bool_<__is_trivially_assignable(T &, Arg &&)>
{};
template<typename T, typename... Args>
using is_trivially_constructible =
meta::bool_<__is_trivially_constructible(T, Args...)>;
template<typename T>
using is_trivially_default_constructible =
is_trivially_constructible<T>;
template<typename T>
using is_trivially_copy_constructible =
is_trivially_constructible<T, T const &>;
template<typename T>
using is_trivially_move_constructible =
is_trivially_constructible<T, T>;
template<typename T, typename U>
using is_trivially_assignable =
meta::bool_<__is_trivially_assignable(T, U)>;
template<typename T>
using is_trivially_copy_assignable =
is_trivially_assignable<T &, T const &>;
template<typename T>
using is_trivially_move_assignable =
is_trivially_assignable<T &, T>;
template<typename T>
using is_trivially_copyable =
meta::bool_<__is_trivially_copyable(T)>;
#elif defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
template<typename T>
using is_trivially_default_constructible = std::is_trivial<T>;
template<typename T>
using is_trivially_copy_constructible = std::is_trivial<T>;
template<typename T>
using is_trivially_move_constructible = std::is_trivial<T>;
template<typename T>
using is_trivially_copy_assignable = std::is_trivial<T>;

template<typename T>
using is_trivially_move_assignable = std::is_trivial<T>;
template<typename T>
using is_trivially_copyable = std::is_trivial<T>;
#else
template<typename T>
using is_trivially_default_constructible =
std::is_trivially_constructible<T>;
using std::is_trivially_copy_constructible;
using std::is_trivially_move_constructible;
using std::is_trivially_copy_assignable;
using std::is_trivially_move_assignable;
using std::is_trivially_copyable;
#endif

#if RANGES_CXX_LIB_IS_FINAL > 0
Expand Down
Loading

0 comments on commit 3a074ed

Please sign in to comment.