Skip to content

Commit

Permalink
Please merge me! I caaaan't wait!
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanMabille committed Jul 12, 2024
1 parent 3830cbc commit 760c3ff
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 16 deletions.
7 changes: 4 additions & 3 deletions include/sparrow/mp_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ namespace sparrow::mpl
#endif
}

/// The boolean_like concept specifies that a type can be convertible to and assignable from
/// bool.
/// Matches types that can be convertible to and assignable from bool. We do not use
/// `std::convertible_to` because we don't want to impose an implicit conversion.
template <class T>
concept boolean_like = std::is_assignable_v<std::add_lvalue_reference_t<T>, bool> and std::convertible_to<T, bool>;
concept boolean_like = std::is_assignable_v<std::add_lvalue_reference_t<T>, bool> and
requires { static_cast<bool>(std::declval<T>()); };
}
25 changes: 14 additions & 11 deletions include/sparrow/nullable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace sparrow

private:

static constexpr const char* message = "Invalid access to null value";
static constexpr const char* message = "Invalid access to nullable underlying value";
};

/**
Expand Down Expand Up @@ -171,20 +171,23 @@ namespace sparrow
}

/**
* The nullable class models a value or a reference that can be "null", or missing.
* The nullable class models a value or a reference that can be "null", or missing,
* like values traditionally used in data science libraries.
* The flag indicating whether the element should be considered missing can be a
* boolean-like value or reference.
*
* The value is always available, independently from the value of the flag. The flag
* only indicates whether the value should be considered for computation.
* The value is always valid, independently from the value of the flag. The flag
* only indicates whether the value should be considered as specified (flag is true)
* or null (flag is false). Assigning nullval to a nullable or setting its flag to
* flase does not trigger the destruction of the underlying value.
*
* When it holds a value, the nullable class has a regular value semantics: copying
* or moving it will copy or move the underlygin value and flag. When it holds a
* reference, the nullable class has a view semantics: copying it or moving it will
* copy the underlying value and flag instead of reassigining the references. This
* allows to create nullable views over two distinct arrays (one for the values, one
* for the flags) used to implement a stl-like contianer of nullable. For instance,
* if you have the following class:
* When the stored object is not a reference, the nullable class has a regular value
* semantics: copying or moving it will copy or move the underlying value and flag.
* When the stored object is a reference, the nullable class has a view semantics:
* copying it or moving it will copy the underlying value and flag instead of reassigining
* the references. This allows to create nullable views over two distinct arrays (one
* for the values, one for the flags) used to implement a stl-like contianer of nullable.
* For instance, if you have the following class:
*
* @code{.cpp}
* template <class T, class B>
Expand Down
2 changes: 1 addition & 1 deletion test/test_mpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace sparrow
{
public:
like_a_bool& operator=(const bool&) { return *this; }
operator bool() const { return true; }
explicit operator bool() const { return true; }
};

static_assert(mpl::boolean_like<like_a_bool>);
Expand Down
9 changes: 8 additions & 1 deletion test/test_nullable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,27 @@

#include <string>
#include <tuple>
#include <vector>

#include "sparrow/nullable.hpp"

#include "doctest/doctest.h"

namespace sparrow
{
// Custom type that increments a counter
// when an instane is move constructed or
// move assigned (and decrements it upon
// deletion). This allows to test that
// nullable views do not move their underlying
// data upon assignment.
class Custom
{
public:

static int counter;

explicit Custom(const int& i = 0)
explicit Custom(int i = 0)
: m_value(i)
{
}
Expand Down

0 comments on commit 760c3ff

Please sign in to comment.