Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added reference_proxy and bitset_view #13

Closed
wants to merge 6 commits into from

Conversation

JohanMabille
Copy link
Collaborator

No description provided.

Copy link
Collaborator

@jjerphan jjerphan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A first pass.

include/sparrow/buffer.hpp Outdated Show resolved Hide resolved
test/test_array_data.cpp Outdated Show resolved Hide resolved
include/sparrow/array_data.hpp Outdated Show resolved Hide resolved
include/sparrow/data_type.hpp Show resolved Hide resolved
include/sparrow/array_data.hpp Outdated Show resolved Hide resolved
{
public:

using self_type = reference_proxy<T>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference goes to this_type but ok

template <class U>
self_type& operator/=(const U&);

operator const_reference() const;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be explicit.

Copy link
Collaborator Author

@JohanMabille JohanMabille Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires that you explicitly cast each time you want to compare the proxy to a value (for instance), which is paricularly ugly (and does not looks naturaly at all to me):

template <class T>
struct array_impl
{
    using reference = reference_proxy<std::uint8_t>;
    const_reference = const std::uint8_t&;

    using size_type = std::size_t;

    reference operator[](size_type i);
};

array<std::uint8_t> a = ....;
uint8_t expected = 8u;
// With explicit you need to
using const_reference = array<std::uint8_t>::const_reference;
bool b = (const_reference(a[i]) == expected);

// while without, you can simply write:
bool b = a[i] == expected;

How having this operator implicit can be harmful?

Copy link
Collaborator

@Klaim Klaim Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How having this operator implicit can be harmful?

See this guideline for the fundations of why it's a very bad idea. It goes in pair with the guideline about conversion operator that must also be explicit. The cases where this would not work as so rare I, so far, never saw a justifyiable example that isn't improved by explicit.

This requires that you explicitly cast each time you want to compare the proxy to a value (for instance), which is paricularly ugly (and does not looks naturaly at all to me):

That just means that the reference type needs comparison operators with objects of the type being referred to. That conversion is a shortctut that can cause more issues than explicitly stating these operators.

Also note that even like that "ugly" is not a reason to make the code potentially silently incorrect, in particular in a C++ library supposedly trying to make correctness easier than the C api. Worst scenario, static_casts are fine and help clarify where are the potential issues related to conversion. They are noisy for a reason after all.

See as example: https://godbolt.org/z/7jxcvjq3Y

I see no reason to make that operator implicit.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot a test in my example, here is the udpated version (I only added the test): https://godbolt.org/z/TYx7sGezj

include/sparrow/array_data.hpp Outdated Show resolved Hide resolved
#include "sparrow/dynamic_bitset.hpp"
#include "sparrow/data_type.hpp"

namespace sparrow
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some documentation for each one of these types?


reference back();
const_reference back() const;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about begin and end? Is this not a range/container?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah they should be, and I want to refactor this hierarchy to be consistent with the dynamic bitset. We can add it in an incoming PR though, to keep this one quite "small" (it is actually already big)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding TODOs for these so that we dont forget in further passes.

include/sparrow/buffer.hpp Show resolved Hide resolved
template <class T>
void buffer<T>::resize(size_type n, value_type value)
{
size_type old_size = size();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

{
public:

constexpr explicit data_descriptor(data_type id = data_type::UINT8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a separate default constructor which calls the explicit constructor with 1 parameter. That we we dont have an explicit default constructor.

template <class B>
void dynamic_bitset_base<B>::resize(size_type n, value_type b)
{
size_type old_block_count = m_buffer.size();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Collaborator

@jjerphan jjerphan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another pass.

Comment on lines +36 to +37
std::vector<buffer<block_type>> buffers;
std::vector<array_data> child_data;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be used instead?

Suggested change
std::vector<buffer<block_type>> buffers;
std::vector<array_data> child_data;
buffer<buffer<block_type>> buffers;
buffer<array_data> child_data;

include/sparrow/buffer.hpp Show resolved Hide resolved
buffer<T>::buffer(size_type size, value_type value)
: base_type{allocate(size), size}
{
std::fill(data(), data() + size, value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative.

Suggested change
std::fill(data(), data() + size, value);
std::fill_n(data(), size, value);

resize(n);
if (old_size < n)
{
std::fill(data() + old_size, data() + n, value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, one can use:

Suggested change
std::fill(data() + old_size, data() + n, value);
std::fill_n(data() + old_size, n, value);

CHECK_EQ(b.size(), size1);
CHECK_EQ(b.data()[2], 2);

const std::size_t size3 = 6u;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move it above?

bitmap b3(buf, expected_block_count * 8);

b2 = b3;
CHECK_EQ(b2.size() , b3.size());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CHECK_EQ(b2.size() , b3.size());
CHECK_EQ(b2.size(), b3.size());

auto dynamic_bitset_base<B>::count_non_null() const noexcept -> size_type
{
// Number of bits set to 1 in i for i from 0 to 255
static constexpr unsigned char table[] =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the comment sufficient?

@JohanMabille
Copy link
Collaborator Author

JohanMabille commented Mar 11, 2024

Converted to draft to avoid accidental merge. This PR will be split into many smaller ones.

@JohanMabille JohanMabille mentioned this pull request Mar 11, 2024
@jjerphan
Copy link
Collaborator

Can this PR be closed now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants