Skip to content

Commit

Permalink
Merge pull request #106 from tcbrindle/pr/modules_experiment
Browse files Browse the repository at this point in the history
Initial, experimental modules support
  • Loading branch information
tcbrindle authored Jul 28, 2023
2 parents 0a0abbb + 141f271 commit 390c752
Show file tree
Hide file tree
Showing 77 changed files with 234 additions and 131 deletions.
7 changes: 4 additions & 3 deletions include/flux/core/assert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace flux {

FLUX_EXPORT
struct unrecoverable_error : std::logic_error {
explicit unrecoverable_error(char const* msg) : std::logic_error(msg) {}
};
Expand Down Expand Up @@ -44,7 +45,7 @@ struct runtime_error_fn {

}

inline constexpr auto runtime_error = detail::runtime_error_fn{};
FLUX_EXPORT inline constexpr auto runtime_error = detail::runtime_error_fn{};

namespace detail {

Expand All @@ -71,8 +72,8 @@ struct bounds_check_fn {

} // namespace detail

inline constexpr auto assert_ = detail::assert_fn{};
inline constexpr auto bounds_check = detail::bounds_check_fn{};
FLUX_EXPORT inline constexpr auto assert_ = detail::assert_fn{};
FLUX_EXPORT inline constexpr auto bounds_check = detail::bounds_check_fn{};

#define FLUX_ASSERT(cond) (::flux::assert_(cond, "assertion '" #cond "' failed"))

Expand Down
23 changes: 23 additions & 0 deletions include/flux/core/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ namespace flux {
/*
* Cursor concepts
*/
FLUX_EXPORT
template <typename Cur>
concept cursor = std::movable<Cur>;

FLUX_EXPORT
template <typename Cur>
concept regular_cursor = cursor<Cur> && std::regular<Cur>;

FLUX_EXPORT
template <typename Cur>
concept ordered_cursor =
regular_cursor<Cur> &&
Expand All @@ -40,6 +43,7 @@ concept ordered_cursor =
* Sequence concepts and associated types
*/

FLUX_EXPORT
template <typename T>
struct sequence_traits;

Expand All @@ -50,9 +54,11 @@ using traits_t = sequence_traits<std::remove_cvref_t<T>>;

} // namespace detail

FLUX_EXPORT
template <typename Seq>
using cursor_t = decltype(detail::traits_t<Seq>::first(FLUX_DECLVAL(Seq&)));

FLUX_EXPORT
template <typename Seq>
using element_t = decltype(detail::traits_t<Seq>::read_at(FLUX_DECLVAL(Seq&), FLUX_DECLVAL(cursor_t<Seq> const&)));

Expand Down Expand Up @@ -93,19 +99,25 @@ struct rvalue_element_type<T> {

} // namespace detail

FLUX_EXPORT
template <typename Seq>
using value_t = typename detail::value_type<Seq>::type;

FLUX_EXPORT
using distance_t = flux::config::int_type;

FLUX_EXPORT
using index_t = flux::config::int_type;

FLUX_EXPORT
template <typename Seq>
using rvalue_element_t = typename detail::rvalue_element_type<Seq>::type;

FLUX_EXPORT
template <typename Seq>
using common_element_t = std::common_reference_t<element_t<Seq>, value_t<Seq>&>;

FLUX_EXPORT
template <typename Seq>
using const_element_t = std::common_reference_t<value_t<Seq> const&&, element_t<Seq>>;

Expand Down Expand Up @@ -144,6 +156,7 @@ concept sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept sequence = detail::sequence_concept<Seq>;

Expand All @@ -159,6 +172,7 @@ inline constexpr bool disable_multipass<T> = T::disable_multipass;

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept multipass_sequence =
sequence<Seq> && regular_cursor<cursor_t<Seq>> &&
Expand All @@ -175,6 +189,7 @@ concept bidirectional_sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept bidirectional_sequence = detail::bidirectional_sequence_concept<Seq>;

Expand All @@ -192,6 +207,7 @@ concept random_access_sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept random_access_sequence = detail::random_access_sequence_concept<Seq>;

Expand All @@ -208,6 +224,7 @@ concept contiguous_sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept contiguous_sequence = detail::contiguous_sequence_concept<Seq>;

Expand All @@ -222,6 +239,7 @@ concept bounded_sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept bounded_sequence = detail::bounded_sequence_concept<Seq>;

Expand All @@ -238,9 +256,11 @@ concept sized_sequence_concept =

} // namespace detail

FLUX_EXPORT
template <typename Seq>
concept sized_sequence = detail::sized_sequence_concept<Seq>;

FLUX_EXPORT
template <typename Seq, typename T>
concept writable_sequence_of =
sequence<Seq> &&
Expand All @@ -260,11 +280,13 @@ inline constexpr bool is_infinite_seq<T> = T::is_infinite;

}

FLUX_EXPORT
template <typename Seq>
concept infinite_sequence =
sequence<Seq> &&
detail::is_infinite_seq<detail::traits_t<Seq>>;

FLUX_EXPORT
template <typename Seq>
concept read_only_sequence =
sequence<Seq> &&
Expand Down Expand Up @@ -292,6 +314,7 @@ concept trivially_copyable_sequence =

}

FLUX_EXPORT
template <typename Seq>
concept adaptable_sequence =
(detail::rvalue_sequence<Seq>
Expand Down
9 changes: 9 additions & 0 deletions include/flux/core/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef FLUX_CORE_CONFIG_HPP_INCLUDED
#define FLUX_CORE_CONFIG_HPP_INCLUDED

#include <flux/core/macros.hpp>

#include <concepts>
#include <cstddef>
#include <type_traits>
Expand Down Expand Up @@ -71,11 +73,13 @@

namespace flux {

FLUX_EXPORT
enum class error_policy {
terminate = FLUX_ERROR_POLICY_TERMINATE,
unwind = FLUX_ERROR_POLICY_UNWIND
};

FLUX_EXPORT
enum class overflow_policy {
ignore = FLUX_OVERFLOW_POLICY_IGNORE,
wrap = FLUX_OVERFLOW_POLICY_WRAP,
Expand All @@ -84,16 +88,21 @@ enum class overflow_policy {

namespace config {

FLUX_EXPORT
using int_type = FLUX_INT_TYPE;
static_assert(std::signed_integral<int_type> && (sizeof(int_type) >= sizeof(std::ptrdiff_t)),
"Custom FLUX_INT_TYPE must be a signed integer type at least as large as ptrdiff_t");

FLUX_EXPORT
inline constexpr error_policy on_error = static_cast<error_policy>(FLUX_ERROR_POLICY);

FLUX_EXPORT
inline constexpr overflow_policy on_overflow = static_cast<overflow_policy>(FLUX_OVERFLOW_POLICY);

FLUX_EXPORT
inline constexpr bool print_error_on_terminate = FLUX_PRINT_ERROR_ON_TERMINATE;

FLUX_EXPORT
inline constexpr bool enable_debug_asserts = FLUX_ENABLE_DEBUG_ASSERTS;

} // namespace config
Expand Down
42 changes: 22 additions & 20 deletions include/flux/core/functional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace flux {

FLUX_EXPORT
template <typename Fn, typename Proj = std::identity>
struct proj {
Fn fn;
Expand All @@ -38,6 +39,7 @@ struct proj {
template <typename F, typename P = std::identity>
proj(F, P = {}) -> proj<F, P>;

FLUX_EXPORT
template <typename Fn, typename Lhs = std::identity, typename Rhs = std::identity>
struct proj2 {
Fn fn;
Expand Down Expand Up @@ -120,7 +122,7 @@ struct unpack_fn {

} // namespace detail

inline constexpr auto unpack = detail::unpack_fn{};
FLUX_EXPORT inline constexpr auto unpack = detail::unpack_fn{};

namespace pred {

Expand All @@ -142,7 +144,7 @@ inline constexpr auto cmp = [](auto&& val) {
} // namespace detail

/// Given a predicate, returns a new predicate with the condition reversed
inline constexpr auto not_ = [](auto&& pred) {
FLUX_EXPORT inline constexpr auto not_ = [](auto&& pred) {
return detail::predicate([p = FLUX_FWD(pred)] (auto const&... args) {
return !std::invoke(p, FLUX_FWD(args)...);
});
Expand All @@ -153,7 +155,7 @@ inline constexpr auto not_ = [](auto&& pred) {
///
/// The returned predicate is short-circuiting: if the first predicate returns
/// `false`, the second will not be evaluated.
inline constexpr auto both = [](auto&& p, auto&& and_) {
FLUX_EXPORT inline constexpr auto both = [](auto&& p, auto&& and_) {
return detail::predicate{[p1 = FLUX_FWD(p), p2 = FLUX_FWD(and_)] (auto const&... args) {
return std::invoke(p1, args...) && std::invoke(p2, args...);
}};
Expand All @@ -164,7 +166,7 @@ inline constexpr auto both = [](auto&& p, auto&& and_) {
///
/// The returned predicate is short-circuiting: if the first predicate returns
/// `true`, the second will not be evaluated
inline constexpr auto either = [](auto&& p, auto&& or_) {
FLUX_EXPORT inline constexpr auto either = [](auto&& p, auto&& or_) {
return detail::predicate{[p1 = FLUX_FWD(p), p2 = FLUX_FWD(or_)] (auto const&... args) {
return std::invoke(p1, args...) || std::invoke(p2, args...);
}};
Expand Down Expand Up @@ -197,55 +199,55 @@ constexpr auto operator||(detail::predicate<L> lhs, detail::predicate<R> rhs)
///
/// The returned predicate is short-circuiting: if the first predicate returns
/// `true`, the second will not be evaluated.
inline constexpr auto neither = [](auto&& p1, auto&& nor) {
FLUX_EXPORT inline constexpr auto neither = [](auto&& p1, auto&& nor) {
return not_(either(FLUX_FWD(p1), FLUX_FWD(nor)));
};

inline constexpr auto eq = detail::cmp<std::ranges::equal_to>;
inline constexpr auto neq = detail::cmp<std::ranges::not_equal_to>;
inline constexpr auto lt = detail::cmp<std::ranges::less>;
inline constexpr auto gt = detail::cmp<std::ranges::greater>;
inline constexpr auto leq = detail::cmp<std::ranges::less_equal>;
inline constexpr auto geq = detail::cmp<std::ranges::greater_equal>;
FLUX_EXPORT inline constexpr auto eq = detail::cmp<std::ranges::equal_to>;
FLUX_EXPORT inline constexpr auto neq = detail::cmp<std::ranges::not_equal_to>;
FLUX_EXPORT inline constexpr auto lt = detail::cmp<std::ranges::less>;
FLUX_EXPORT inline constexpr auto gt = detail::cmp<std::ranges::greater>;
FLUX_EXPORT inline constexpr auto leq = detail::cmp<std::ranges::less_equal>;
FLUX_EXPORT inline constexpr auto geq = detail::cmp<std::ranges::greater_equal>;

/// A predicate which always returns true
inline constexpr auto true_ = detail::predicate{[](auto const&...) -> bool { return true; }};
FLUX_EXPORT inline constexpr auto true_ = detail::predicate{[](auto const&...) -> bool { return true; }};

/// A predicate which always returns false
inline constexpr auto false_ = detail::predicate{[](auto const&...) -> bool { return false; }};
FLUX_EXPORT inline constexpr auto false_ = detail::predicate{[](auto const&...) -> bool { return false; }};

/// Identity predicate, returns the boolean value given to it
inline constexpr auto id = detail::predicate{[](bool b) -> bool { return b; }};
FLUX_EXPORT inline constexpr auto id = detail::predicate{[](bool b) -> bool { return b; }};

/// Returns true if the given value is greater than a zero of the same type.
inline constexpr auto positive = detail::predicate{[](auto const& val) -> bool {
FLUX_EXPORT inline constexpr auto positive = detail::predicate{[](auto const& val) -> bool {
return val > decltype(val){0};
}};

/// Returns true if the given value is less than a zero of the same type.
inline constexpr auto negative = detail::predicate{[](auto const& val) -> bool {
FLUX_EXPORT inline constexpr auto negative = detail::predicate{[](auto const& val) -> bool {
return val < decltype(val){0};
}};

/// Returns true if the given value is not equal to a zero of the same type.
inline constexpr auto nonzero = detail::predicate{[](auto const& val) -> bool {
FLUX_EXPORT inline constexpr auto nonzero = detail::predicate{[](auto const& val) -> bool {
return val != decltype(val){0};
}};

/// Given a sequence of values, constructs a predicate which returns true
/// if its argument compares equal to one of the values
inline constexpr auto in = [](auto const&... vals) requires (sizeof...(vals) > 0)
FLUX_EXPORT inline constexpr auto in = [](auto const&... vals) requires (sizeof...(vals) > 0)
{
return detail::predicate{[vals...](auto const& arg) -> bool {
return ((arg == vals) || ...);
}};
};

inline constexpr auto even = detail::predicate([](auto const& val) -> bool {
FLUX_EXPORT inline constexpr auto even = detail::predicate([](auto const& val) -> bool {
return val % decltype(val){2} == decltype(val){0};
});

inline constexpr auto odd = detail::predicate([](auto const& val) -> bool {
FLUX_EXPORT inline constexpr auto odd = detail::predicate([](auto const& val) -> bool {
return val % decltype(val){2} != decltype(val){0};
});

Expand Down
2 changes: 2 additions & 0 deletions include/flux/core/inline_sequence_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace flux {

FLUX_EXPORT
template <cursor Cur>
struct bounds {
FLUX_NO_UNIQUE_ADDRESS Cur from;
Expand All @@ -23,6 +24,7 @@ struct bounds {
template <cursor Cur>
bounds(Cur, Cur) -> bounds<Cur>;

FLUX_EXPORT
template <sequence Seq>
using bounds_t = bounds<cursor_t<Seq>>;

Expand Down
6 changes: 6 additions & 0 deletions include/flux/core/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,10 @@
::flux::inc(_flux_seq_, _flux_cur_)) \
if (_flux_var_decl_ = ::flux::read_at(_flux_seq_, _flux_cur_); true)

#ifdef FLUX_MODULE_INTERFACE
#define FLUX_EXPORT export
#else
#define FLUX_EXPORT
#endif

#endif // FLUX_CORE_MACROS_HPP_INCLUDED
Loading

0 comments on commit 390c752

Please sign in to comment.