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

initial version of InlineVector #3

Closed
wants to merge 3 commits into from

Conversation

novakovicdj
Copy link
Owner

Copy link

@CAHEK7 CAHEK7 left a comment

Choose a reason for hiding this comment

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

Also could you add modifiers like

clear
push_back
emplace_back
pop_back
resize

Please refer to the std::vector implementation.

The rest of modifiers like

insert 
emplace
erase
swap

probably are not so important, but much mor complex.


InlineVector(std::initializer_list<T> _data) : real_size(_data.size())
{
if(_data.size() > N)
Copy link

Choose a reason for hiding this comment

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

You can actually use real_size here. It is already initialized.
(see the comment about real_size itself down below)

Comment on lines 55 to 64
template <typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>>
InlineVector(_InputIterator first, _InputIterator last)
{
if(std::distance(first, last) > N)
{
MIOPEN_THROW("Input data size is bigger than InlineVector's capacity");
}
std::copy(first, last, data.begin());
real_size = std::distance(first, last);
}
Copy link

Choose a reason for hiding this comment

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

You can do exactly the same as in the InlineVector(std::initializer_list<T> _data) constructor, like : real_size(std::distance(...)).


private:
std::array<T, N> data;
uint8_t real_size;
Copy link

Choose a reason for hiding this comment

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

Even if real size (and N) can be relatively small, it's better keeping it as size_t. Most probably from 3 to 7 bytes will be consumed by padding.
Also it is better to keep some consistency between all the container implementations and it's safer to assign anything to that size_t real_size - assigning to int/uint8 may lead to some unexpected truncations.

Comment on lines 77 to 79
T& operator[](std::size_t n) { return data[n]; }

const T& operator[](std::size_t n) const { return data[n]; }
Copy link

Choose a reason for hiding this comment

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

I would add method .at() which checks the boundaries and throw.

bool empty() const { return real_size == 0; }

// Real size
uint8_t size() const { return real_size; }
Copy link

Choose a reason for hiding this comment

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

Suggested change
uint8_t size() const { return real_size; }
uint8_t size() const noexcept { return real_size; }

The other tiny methods should have noexcept (like operators, iterators, etc, I guess almost all of the methods)

std::reverse_iterator<T*> rend() { return std::reverse_iterator<T*>(begin()); }

// Element access
T& operator[](std::size_t n) { return data[n]; }
Copy link

Choose a reason for hiding this comment

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

Also front(), back() and data() methods should be added.

Comment on lines 60 to 63
auto first_not_one_in_v2 =
std::find_if(in_v2.rbegin(), in_v2.rend(), [](int i) { return i != 1; });
auto first_note_one_v2 = std::find_if(v2.rbegin(), v2.rend(), [](int i) { return i != 1; });
EXPECT_EQ(*first_not_one_in_v2, *first_note_one_v2);
Copy link

Choose a reason for hiding this comment

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

If something got broken, first_not_one_in_v2 can be end() and EXPECT_EQ has undefined behavior and does not check anything.

Probably std::distance check should be done prior to the value check.

Comment on lines +48 to +49
int sum_in_v1 = std::accumulate(in_v1.begin(), in_v1.end(), 0);
int sum_v1 = std::accumulate(v1.begin(), v1.end(), 0);
Copy link

Choose a reason for hiding this comment

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

I know that both vectors are 4, 2, 1, but accumulating size_t to int usually is not a good idea (it's not just int sum, the most important is the last parameter of std::accumulate).
Probably it's simpler to make both vectors int.

Comment on lines 99 to 101
const T* cbegin() const noexcept { return _data.cbegin(); }

const T* cend() const noexcept { return (_data.cbegin() + real_size); }
Copy link

Choose a reason for hiding this comment

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

it automatically resolves a const version

Suggested change
const T* cbegin() const noexcept { return _data.cbegin(); }
const T* cend() const noexcept { return (_data.cbegin() + real_size); }
const T* cbegin() const noexcept { return begin(); }
const T* cend() const noexcept { return end(); }

{
MIOPEN_THROW("Cannot get back element, InlineVector is empty");
}
return *(end() - 1);
Copy link

Choose a reason for hiding this comment

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

Suggested change
return *(end() - 1);
return *std::prev(end());;

Usually front/back functions do not check ranges. but probably it's ok.

Comment on lines 197 to 205
void resize(std::size_t n)
{
if(n > N)
{
MIOPEN_THROW("It is not possible to resize beyond capacity");
}

real_size = n;
}
Copy link

Choose a reason for hiding this comment

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

That is actually

Suggested change
void resize(std::size_t n)
{
if(n > N)
{
MIOPEN_THROW("It is not possible to resize beyond capacity");
}
real_size = n;
}
void resize(std::size_t n)
{
resize(n, T{});
}

}

// Remove element from the back
void pop_back() noexcept { real_size = ((real_size - 1) >= 0) ? (real_size - 1) : 0; }
Copy link

Choose a reason for hiding this comment

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

Suggested change
void pop_back() noexcept { real_size = ((real_size - 1) >= 0) ? (real_size - 1) : 0; }
void pop_back() noexcept { real_size = (real_size > 1) ? (real_size - 1) : 0; }

void pop_back() noexcept { real_size = ((real_size - 1) >= 0) ? (real_size - 1) : 0; }

// Clear
constexpr void clear() noexcept { real_size = 0; }
Copy link

Choose a reason for hiding this comment

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

That shouldn't be a constexpr, unless we make some extra efforts to make the whole class constexpr friendly.
While capacity can be, should be and it is constexpr.

@novakovicdj novakovicdj closed this Dec 3, 2024
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.

2 participants