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

Allocator::max_size support in basic_memory_buffer #1960

Merged
merged 1 commit into from
Oct 29, 2020

Conversation

phprus
Copy link
Contributor

@phprus phprus commented Oct 27, 2020

The allocator may have a limit on the size of the allocated memory.

I agree that my contributions are licensed under the {fmt} license, and agree to future changes to the licensing.

@vitaut
Copy link
Contributor

vitaut commented Oct 27, 2020

Thanks for the PR but I don't think it's necessary because allocate should throw if the size exceeds max_size.

@vitaut vitaut closed this Oct 27, 2020
@phprus
Copy link
Contributor Author

phprus commented Oct 27, 2020

If "size <= max_size && new_capacity > max_size" then exception thrown from allocate() will not be correctly.

@vitaut vitaut reopened this Oct 28, 2020
Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

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

This looks reasonable. Please add a unit test and address the inline comments.

Comment on lines 746 to 748
if (size > max_size) {
throw std::length_error("fmt::basic_memory_buffer::grow");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this to reduce the number of checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

Comment on lines 751 to 752
if (new_capacity > max_size) new_capacity = max_size;
if (size > new_capacity) new_capacity = size; // size is never greater max_size.
Copy link
Contributor

@vitaut vitaut Oct 28, 2020

Choose a reason for hiding this comment

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

We only need to check new_capacity if it is not greater than size. The rest allocate will take care of. Something like:

if (size > new_capacity) new_capacity = size;
else if (new_capacity > max_size) new_capacity = (std::max)(size, max_size);

@phprus
Copy link
Contributor Author

phprus commented Oct 28, 2020

Commit updated.

Comment on lines 60 to 78
template <typename Allocator, size_t MaxSize>
class allocator_max_size: public Allocator {
public:
typedef typename Allocator::value_type value_type;
size_t max_size() const FMT_NOEXCEPT {
return MaxSize;
}
value_type* allocate(size_t n) {
if (n > max_size()) {
throw std::length_error("size > max_size");
}
return std::allocator_traits<Allocator>::allocate(
*static_cast<Allocator *>(this), n);
}
void deallocate(value_type* p, size_t n) {
std::allocator_traits<Allocator>::deallocate(
*static_cast<Allocator *>(this), p, n);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Please move this to the format-test.cc since it's only used there and not a mock.

Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

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

A few more nits, otherwise LGTM

template <typename Allocator, size_t MaxSize>
class allocator_max_size: public Allocator {
public:
typedef typename Allocator::value_type value_type;
Copy link
Contributor

Choose a reason for hiding this comment

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

Here and below: typedef -> using

} catch (const std::exception &) {
throws_on_resize = true;
}
EXPECT_EQ(throws_on_resize, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

EXPECT_TRUE

} catch (const std::exception &) {
throws_on_resize = true;
}
EXPECT_EQ(throws_on_resize, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

EXPECT_TRUE

@phprus phprus requested a review from vitaut October 29, 2020 09:31
@vitaut vitaut merged commit 97c8873 into fmtlib:master Oct 29, 2020
@vitaut
Copy link
Contributor

vitaut commented Oct 29, 2020

Thank you!

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