Skip to content

Commit

Permalink
Merge branch 'master' of github.com:motis-project/utl
Browse files Browse the repository at this point in the history
# Conflicts:
#	include/utl/enumerate.h
  • Loading branch information
felixguendling committed Oct 25, 2024
2 parents 33b6308 + 9a6f1ef commit 8bfa7fc
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 26 deletions.
4 changes: 3 additions & 1 deletion include/utl/cmd_line_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ struct cmd_line_flag : public Tags... {
operator T() { return t; }
T& val() { return t; }
T const& val() const { return t; }
T const& operator*() const { return t; }
T& operator*() { return t; }
T t{};
};

template <typename T>
inline T parse(int argc, char const** argv) {
inline T parse_flags(int argc, char const** argv) {
auto parse_flag = [](auto& val, cstr next_arg) {
using FieldType = std::remove_cv_t<std::remove_reference_t<decltype(val)>>;
if constexpr (std::is_same_v<FieldType, bool>) {
Expand Down
6 changes: 3 additions & 3 deletions include/utl/enumerate.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct iterator {
using reference = value_type;
using pointer = std::add_pointer_t<value_type>;

difference_type operator-(iterator const& o) {
difference_type operator-(iterator const& o) const {
return static_cast<std::ptrdiff_t>(i_) - static_cast<std::ptrdiff_t>(o.i_);
}

Expand All @@ -37,13 +37,13 @@ struct iterator {
--iter_;
}

iterator operator++(int) {
iterator operator++(int) const {
auto tmp = *this;
++(*this);
return tmp;
}

iterator operator--(int)
iterator operator--(int) const
requires(std::bidirectional_iterator<It>)
{
auto tmp = *this;
Expand Down
32 changes: 27 additions & 5 deletions include/utl/init_from.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,18 @@ struct is_complete {
};

struct wildcard {
#ifdef _MSC_VER
template <typename T>
operator T&() const;
#else
template <typename T>
operator T&&() const;

template <typename T>
operator T&() const
requires std::disjunction_v<std::negation<is_complete<T>>,
std::is_copy_constructible<T>>;
#endif
};

template <std::size_t N = 0>
Expand Down Expand Up @@ -273,11 +283,17 @@ template <typename T>
using deref_t = decltype(*std::declval<T>());

template <typename T, typename U>
struct deref_same {
struct deref_second_same {
static constexpr auto const value =
std::is_same_v<T, std::decay_t<deref_t<U>>>;
};

template <typename T, typename U>
struct deref_both_same {
static constexpr auto const value =
std::is_same_v<std::decay_t<deref_t<T>>, std::decay_t<deref_t<U>>>;
};

template <typename T, typename S, std::size_t I = 0U>
bool c(S&& s) {
using Src = std::decay_t<std::tuple_element_t<I, std::decay_t<S>>>;
Expand All @@ -286,24 +302,30 @@ bool c(S&& s) {
if constexpr (std::is_same_v<Target, Src>) {
return true;
} else if constexpr (std::conjunction_v<derefable<Src>,
deref_same<Target, Src>>) {
deref_second_same<Target, Src>>) {
return std::get<I>(s) != nullptr;
} else if constexpr (std::conjunction_v<derefable<Src>, derefable<Target>,
deref_both_same<Target, Src>>) {
return true;
} else {
static_assert(I + 1U < std::tuple_size_v<std::decay_t<S>>);
return c<T, S, I + 1U>(std::forward<S>(s));
}
}

template <typename T, typename S, std::size_t I = 0U>
T& m(S&& s) {
std::conditional_t<std::is_pointer_v<std::decay_t<T>>, T, T&> m(S&& s) {
using Src = std::decay_t<std::tuple_element_t<I, std::decay_t<S>>>;
using Target = std::decay_t<T>;

if constexpr (std::is_same_v<Target, Src>) {
return std::get<I>(s);
} else if constexpr (std::conjunction_v<derefable<Src>,
deref_same<Target, Src>>) {
deref_second_same<Target, Src>>) {
return *std::get<I>(s);
} else if constexpr (std::conjunction_v<derefable<Src>, derefable<Target>,
deref_both_same<Target, Src>>) {
return std::get<I>(s) == nullptr ? nullptr : &*std::get<I>(s);
} else {
static_assert(I + 1U < std::tuple_size_v<std::decay_t<S>>);
return m<T, S, I + 1U>(std::forward<S>(s));
Expand All @@ -316,7 +338,7 @@ std::optional<T> init_from(S&& s, std::index_sequence<I...>) {
if (!(c<std::tuple_element_t<I, Tuple>>(s) && ...)) {
return std::nullopt;
}
return T{m<std::tuple_element_t<I, Tuple>>(s)...};
return T{m<std::decay_t<std::tuple_element_t<I, Tuple>>>(s)...};
}

} // namespace detail
Expand Down
3 changes: 3 additions & 0 deletions include/utl/sort_by.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace utl {
template <typename T>
void apply_permutation(std::vector<unsigned> const& permutation, T const& orig,
T& vec) {
if (vec.empty()) {
return;
}
for (auto i = 0U; i != permutation.size(); ++i) {
vec[i] = orig[permutation[i]];
}
Expand Down
4 changes: 2 additions & 2 deletions test/cmd_line_parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ constexpr auto const expected_description =

TEST(cmd, cmd_line_flag_test) {
char const* args[] = {"./exe", "-c", "--file", "test", "--num_threads", "8"};
auto c = parse<config>(sizeof(args) / sizeof(char const*), args);
auto c = parse_flags<config>(sizeof(args) / sizeof(char const*), args);

EXPECT_TRUE(c.capture_.val());
EXPECT_TRUE(c.file_.val() == "test");
Expand All @@ -35,7 +35,7 @@ TEST(cmd, cmd_line_flag_required_test) {

bool thrown = false;
try {
parse<config>(sizeof(args) / sizeof(char const*), args);
parse_flags<config>(sizeof(args) / sizeof(char const*), args);
} catch (...) {
thrown = true;
}
Expand Down
25 changes: 10 additions & 15 deletions test/init_from_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include "utl/init_from.h"

/* not working currently
struct a {
int& i_;
float& j_;
Expand All @@ -15,38 +14,31 @@ struct b {
int y_;
};

template <typename T>
concept C3 = requires(T t) {
T{utl::detail::wildcard{}, utl::detail::wildcard{}, utl::detail::wildcard{}};
};
static_assert(C3<a>);
static_assert(C3<b>);
TEST(init_from, init_from) {
struct test {};

struct a {
int& i_;
float& j_;
int& k_;
test* str_;
};

struct b {
double z_;
std::unique_ptr<float> x_;
int y_;
std::unique_ptr<test> str_;
};

static_assert(utl::detail::is_brace_constructible<b, 3U>());
static_assert(utl::detail::arity<a>() == 3U);
static_assert(utl::detail::arity<b>() == 3U);
auto src = b{0.0, std::make_unique<float>(10.0F), 42};
auto src = b{0.0, std::make_unique<float>(10.0F), 42, nullptr};
auto tgt = utl::init_from<a>(src);
ASSERT_TRUE(tgt.has_value());

EXPECT_EQ(42, tgt->i_);
EXPECT_EQ(10.0F, tgt->j_);
EXPECT_EQ(42, tgt->k_);
EXPECT_EQ(nullptr, tgt->str_);

tgt->i_ = 7.0F;
tgt->j_ = 77.0F;
Expand All @@ -58,5 +50,8 @@ TEST(init_from, init_from) {

auto no = utl::init_from<a>(b{});
EXPECT_FALSE(no.has_value());

src.str_ = std::make_unique<test>();
auto tgt1 = utl::init_from<a>(src);
EXPECT_EQ(tgt1->str_, src.str_.get());
};
*/

0 comments on commit 8bfa7fc

Please sign in to comment.