-
Notifications
You must be signed in to change notification settings - Fork 23
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
Eliminate redundant units from CommonUnit<...>
#310
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,11 @@ struct Prepend; | |
template <typename PackT, typename T> | ||
using PrependT = typename Prepend<PackT, T>::type; | ||
|
||
template <typename T, typename Pack> | ||
struct DropAllImpl; | ||
template <typename T, typename Pack> | ||
using DropAll = typename DropAllImpl<T, Pack>::type; | ||
|
||
template <typename T, typename U> | ||
struct SameTypeIgnoringCvref : std::is_same<stdx::remove_cvref_t<T>, stdx::remove_cvref_t<U>> {}; | ||
|
||
|
@@ -39,11 +44,29 @@ struct AlwaysFalse : std::false_type {}; | |
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// Implementation details below. | ||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// `Prepend` implementation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the point of this comment? Do we need a comment for all inline implementations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Often, the implementation for "public"-ish interface declared up top in a file will depend on new helpers, which I will declare-and-define right next to the "core" implementation. This can get a little messy and confusing, so I use these "section comments" to group things and clarify the purpose. That said, I'm certainly rather inconsistent about using them in practice. |
||
|
||
template <template <typename...> class Pack, typename T, typename... Us> | ||
struct Prepend<Pack<Us...>, T> { | ||
using type = Pack<T, Us...>; | ||
}; | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// `DropAll` implementation. | ||
|
||
// Base case. | ||
template <typename T, template <class...> class Pack> | ||
struct DropAllImpl<T, Pack<>> : stdx::type_identity<Pack<>> {}; | ||
|
||
// Recursive case: | ||
template <typename T, template <class...> class Pack, typename H, typename... Ts> | ||
struct DropAllImpl<T, Pack<H, Ts...>> | ||
: std::conditional<std::is_same<T, H>::value, | ||
DropAll<T, Pack<Ts...>>, | ||
detail::PrependT<DropAll<T, Pack<Ts...>>, H>> {}; | ||
|
||
} // namespace detail | ||
} // namespace au |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to reviewer: if we added only this test case on main, without the fixes, here is what the failure would look like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of checking that they are all consistent with the first element, can we check that they are all equal to a specific unit? That might help test readibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the appeal of this suggestion. I struggled with this for a little bit, but I couldn't see my way to an implementation that did this while keeping the test implementation clean.
One way would be to compare to a desired unit label. But the unit label for common units will change dramatically after 0.4.0 (#105), and I'd hate to have to update this test for that change.
We could also do it by providing the expected type of the common unit. But
CommonUnit<...>
isn't supposed to be named directly by end users: we're supposed to useCommonUnitT<...>
, which performs the de-duping and simplification that is the very thing under test!Ultimately, I think the current approach is the best option available. Phrasing it in terms of order independence, as mentioned in #295 (comment), is the most elegant way I know to express what we're really after here. The downside, as you point out, is that a test failure can't tell you which one is correct; all it can do is point out that they should all be the same, and they're not. But I think in practice this will be good enough to point maintainers in the right direction.