-
Notifications
You must be signed in to change notification settings - Fork 164
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
Introduce official clang-format #596
base: develop
Are you sure you want to change the base?
Conversation
It is manually configured according to what seemed more readable to me. not so useful options or non cpp options are left as default by llvm style |
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.
First, I'm happy to see this initiative moving forward.
How this configuration relates to the initial one and example linked from here #518 (comment) ? Is this significantly different?
I'd like to see some reference to those in this PR.
the example provided in #518 is default LLVM while in this PR it follows our existing example at most of the places and I used all the options so that formatting can be fine-tuned and better. and also some twiques to make this more suitable for us i.e: |
I have not tested this against #87. but I have tested this against our example file(i don't know if they are same), only difference in there(from the few files I tested)
My main test files were kernel.hpp and convolve.hpp |
Do you know if there is any way to tell Currently, this: BOOST_FORCEINLINE
int foo() { return 1 + 2; }
inline
int bar() { return 1 + 2; } becomes this BOOST_FORCEINLINE int
foo()
{
return 1 + 2;
}
inline int bar()
{
return 1 + 2;
} UPDATE: I can not find any option for |
Do you know if there is any way in clang-format 12 to handle the trailing return better way? Here is one bit from template<typename T, typename CS>
auto copy(
boost::gil::pixel<T, CS>* first,
boost::gil::pixel<T, CS>* last,
boost::gil::pixel<T, CS>* dst)
-> boost::gil::pixel<T, CS>*
{
auto p = std::copy((unsigned char*)first, (unsigned char*)last, (unsigned char*)dst);
return reinterpret_cast<boost::gil::pixel<T, CS>*>(p);
} and template <typename T, typename CS>
auto copy(
boost::gil::pixel<T, CS>* first,
boost::gil::pixel<T, CS>* last,
boost::gil::pixel<T, CS>* dst) -> boost::gil::pixel<T, CS>*
{
auto p = std::copy((unsigned char*)first, (unsigned char*)last, (unsigned char*)dst);
return reinterpret_cast<boost::gil::pixel<T, CS>*>(p);
} I like the former. Or, we can just live with the latter :-) |
I think this would also be an opportunity to refactor functions into trailing return type. For example, this input template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t> >::view_t
planar_cmyk_view(std::size_t width, std::size_t height, IC c, IC m, IC y, IC k, std::ptrdiff_t rowsize_in_bytes)
{
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t> >::view_t;
return view_t(width, height, typename view_t::locator(planar_pixel_iterator<IC,cmyk_t>(c,m,y,k), rowsize_in_bytes));
} is reformatted as template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC, cmyk_t>>::view_t planar_cmyk_view(
std::size_t width,
std::size_t height,
IC c,
IC m,
IC y,
IC k,
std::ptrdiff_t rowsize_in_bytes)
{
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC, cmyk_t>>::view_t;
return view_t(
width,
height,
typename view_t::locator(planar_pixel_iterator<IC, cmyk_t>(c, m, y, k), rowsize_in_bytes));
} but if the is changed to trailing return type, then the reformatting output is nicer, I think: template <typename IC>
inline auto planar_cmyk_view(
std::size_t width,
std::size_t height,
IC c,
IC m,
IC y,
IC k,
std::ptrdiff_t rowsize_in_bytes) ->
typename type_from_x_iterator<planar_pixel_iterator<IC, cmyk_t>>::view_t
{
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC, cmyk_t>>::view_t;
return view_t(
width,
height,
typename view_t::locator(planar_pixel_iterator<IC, cmyk_t>(c, m, y, k), rowsize_in_bytes));
} |
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'm happy to go for this - it is good enough and better is evil of good, especially that we have not been able to work out any better for quite some time due to clang-format limitations :-)
We still need to consider how to approach the "big reformat" - see the MongoDB story I linked in #518 (comment)
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see boostorg#596 (comment)
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see boostorg#596 (comment)
It looks like
|
@sdebionne yes clang 12 is required. |
I understand clang 12 is not yet widely available via popular distro packages, but I think we should start using clang-format from the latest release, and keep ourselves updated as soon as new version is released. |
I have another example and question: I run the for (std::ptrdiff_t i = 0; i < 16; i++)
{
- pointers[i] = src_loc.cache_location(points[i][0], points[i][1]);
+ pointers[i] = src_loc.cache_location(points[i][0], points[i][1]);
intensity_array[i] = src_loc[pointers[i]];
} I'm not convinced as it may artificially lengthen lines and cause unnecessary line wrapping. Here is similar situation where all the if (!nonmax || score > fast_score_matrix(j - 1, i)[0] &&
score > fast_score_matrix(j + 1, i)[0] &&
score > fast_score_matrix(j - 1, i - 1)[0] &&
score > fast_score_matrix(j, i - 1)[0] &&
score > fast_score_matrix(j + 1, i - 1)[0] &&
score > fast_score_matrix(j - 1, i + 1)[0] &&
score > fast_score_matrix(j, i + 1)[0] &&
score > fast_score_matrix(j + 1, i + 1)[0])
{
keypoints.push_back(u);
scores.push_back(score);
} I, personally, do not like it as the big blank space to the left is just wasteful - I don't you know but I read from left to right :-) |
.clang-format
Outdated
AccessModifierOffset: -4 | ||
AlignAfterOpenBracket: AlwaysBreak | ||
AlignConsecutiveMacros: AcrossEmptyLinesAndComments | ||
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments |
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.
yes it was intentional, but we can change I don't mind anything in this case
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.
Not big fan of the alignment of =
assignments neither. As of the alignment to the right, I have never seen anything like that before. I am all for a consistent formatting, really don't care too much about the rules as long as they are not too artificial, not too far from what a human developer (think lazy) would write 😁
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.
Good. I don't think I'd ever hit the TAB so many times myself :-)
So, I suggest to avoid those alignments.
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see boostorg#596 (comment)
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see boostorg#596 (comment)
Replying to my own #596 (comment)
There is a way! https://stackoverflow.com/a/60471935/151641 which, I think, we should consider for complex prototypes. For example, without the hack : template <typename String, typename FormatTag, typename ConversionPolicy>
inline auto make_reader(
String const& file_name,
FormatTag const&,
ConversionPolicy const& cc,
typename std::enable_if<
mp11::mp_and<detail::is_supported_path_spec<String>, is_format_tag<FormatTag>>::value>::
type* = nullptr) -> typename get_reader<String, FormatTag, ConversionPolicy>::type
{
return make_reader(file_name, image_read_settings<FormatTag>(), cc);
} and with the hack is better, I think template <typename String, typename FormatTag, typename ConversionPolicy>
inline auto make_reader(
String const& file_name,
FormatTag const&,
ConversionPolicy const& cc,
typename std::enable_if<
mp11::mp_and<detail::is_supported_path_spec<String>, is_format_tag<FormatTag>>::value>::
type* = nullptr) //
-> typename get_reader<String, FormatTag, ConversionPolicy>::type
{
return make_reader(file_name, image_read_settings<FormatTag>(), cc);
} |
This is intermediate commit to clearly show the .clang-format tweaks that I'd like to propose to @lpranam 's original.
I updated this PR with commit a3af622 with proposal of tweaks, please have a look Here is `test.hpp` sample with output of my tweaks
//
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_IO_READ_VIEW_HPP
#define BOOST_GIL_IO_READ_VIEW_HPP
#include <boost/gil/detail/mp11.hpp>
#include <boost/gil/io/base.hpp>
#include <boost/gil/io/conversion_policies.hpp>
#include <boost/gil/io/device.hpp>
#include <boost/gil/io/get_reader.hpp>
#include <boost/gil/io/path_spec.hpp>
#include <boost/mp11.hpp>
#include <type_traits>
namespace boost { namespace gil {
/// \ingroup IO
/// \brief Reads an image view without conversion. No memory is allocated.
/// \param reader An image reader.
/// \param view The image view in which the data is read into.
/// \param settings Specifies read settings depending on the image format.
/// \throw std::ios_base::failure
template <typename Reader, typename View>
inline void read_view(
Reader reader,
View const& view,
typename std::enable_if<mp11::mp_and<
detail::is_reader<Reader>,
typename is_format_tag<typename Reader::format_tag_t>::type,
typename is_read_supported<
typename get_pixel_type<View>::type,
typename Reader::format_tag_t>::type>::value>::type* = nullptr)
{
reader.check_image_size(view.dimensions());
reader.init_view(view, reader._settings);
reader.apply(view);
}
template <typename String, typename FormatTag, typename ConversionPolicy>
inline auto make_reader(
String const& file_name,
FormatTag const&,
ConversionPolicy const& cc,
typename std::enable_if<
mp11::mp_and<detail::is_supported_path_spec<String>, is_format_tag<FormatTag>>::value>::
type* = nullptr) //
-> typename get_reader<String, FormatTag, ConversionPolicy>::type
{
return make_reader(file_name, image_read_settings<FormatTag>(), cc);
}
template <typename FormatTag, typename ConversionPolicy>
inline auto make_reader(
const std::wstring& file_name,
const FormatTag&,
const ConversionPolicy& cc) //
-> typename get_reader<std::wstring, FormatTag, ConversionPolicy>::type
{
return make_reader(file_name, image_read_settings<FormatTag>(), cc);
}
void foo()
{
for (std::ptrdiff_t i = 0; i < 16; i++)
{
pointers[i] = src_loc.cache_location(points[i][0], points[i][1]);
pointers[i] = src_loc.cache_location(points[i][0], points[i][1]) + src_loc[pointers[i]]
- src_loc[pointers[i]];
intensity_array[i] = src_loc[pointers[i]];
}
for (std::ptrdiff_t i = 0; i < 16; i++)
{
if (!nonmax
|| (score > fast_score_matrix(j - 1, i)[0] && score > fast_score_matrix(j + 1, i)[0]
&& score > fast_score_matrix(j - 1, i - 1)[0]
&& score > fast_score_matrix(j, i - 1)[0]
&& score > fast_score_matrix(j + 1, i - 1)[0]
&& score > fast_score_matrix(j - 1, i + 1)[0]
&& score > fast_score_matrix(j, i + 1)[0]
&& score > fast_score_matrix(j + 1, i + 1)[0]))
{
keypoints.push_back(u);
scores.push_back(score);
}
}
if (!nonmax
|| (score > fast_score_matrix(j - 1, i)[0] && score > fast_score_matrix(j + 1, i)[0]
&& score > fast_score_matrix(j - 1, i - 1)[0] && score > fast_score_matrix(j, i - 1)[0]
&& score > fast_score_matrix(j + 1, i - 1)[0]
&& score > fast_score_matrix(j - 1, i + 1)[0] && score > fast_score_matrix(j, i + 1)[0]
&& score > fast_score_matrix(j + 1, i + 1)[0]))
{
keypoints.push_back(u);
scores.push_back(score);
}
}
struct tencil_5points
{
double delta_t = 0.25;
template <typename SubImageView>
auto compute_laplace(SubImageView view, point_t origin)
-> stencil_type<typename SubImageView::value_type>
{
auto current = view(origin);
stencil_type<typename SubImageView::value_type> stencil;
using channel_type = typename channel_type<typename SubImageView::value_type>::type;
std::array<gil::point_t, 8> offsets(get_directed_offsets());
typename SubImageView::value_type zero_pixel;
static_fill(zero_pixel, 0);
for (std::size_t index = 0; index < offsets.size(); ++index)
{
if (index % 2 != 0)
{
static_transform(
view(origin.x + offsets[index].x, origin.y + offsets[index].y),
current,
stencil[index],
std::minus<channel_type>{});
}
else
{
stencil[index] = zero_pixel;
}
}
return stencil;
}
template <typename Pixel>
Pixel reduce(const stencil_type<Pixel>& stencil)
{
auto first = stencil.begin();
auto last = stencil.end();
using channel_type = typename channel_type<Pixel>::type;
auto result = []() {
Pixel zero_pixel;
static_fill(zero_pixel, channel_type(0));
return zero_pixel;
}();
for (std::size_t index : {1u, 3u, 5u, 7u})
{
static_transform(result, stencil[index], result, std::plus<channel_type>{});
}
Pixel delta_t_pixel;
static_fill(delta_t_pixel, delta_t);
static_transform(result, delta_t_pixel, result, std::multiplies<channel_type>{});
return result;
}
};
void foo()
{
}
}} // namespace boost::gil
#endif I think we are close to merge this, once for all and for good :) |
In case anyone is interested, I have just pushed a re-formated I noticed the io extension uses: - template< typename View_Dst
- , typename View_Src
- >
- void copy_data( const View_Dst& dst
- , const View_Src& src
- , typename View_Dst::y_coord_t y
- , std::true_type // is gray1_view
- )
+ template <typename View_Dst, typename View_Src>
+ void copy_data(
+ const View_Dst& dst,
+ const View_Src& src,
+ typename View_Dst::y_coord_t y,
+ std::true_type // is gray1_view I kinda like the comma in front and the closing I'll try to rewrite the complete history and push it in a new fork. |
One more comment: one-liner member functions are now expended: - static void apply(V const &, Value const &) { throw std::bad_cast();}
+ static void apply(V const&, Value const&)
+ {
+ throw std::bad_cast();
+ } Is that configurable? |
@sdebionne Awesome! I'll check it in details later tonight.
It's been my long time preference, especially for members initialisation in constructors e.g. in Boost.Geometry
Yes, |
@sdebionne why try to rewrite the history? boost does not allow force push so ultimately things become not usable in this case? or am I misinterpreting something? |
The branch protection that forbids forced-push is ours in boostorg/gil settings. I recall I was warning you @lpranam about not doing the force-push though :-) However, we, @stefanseefeld and myself, recreated The superproject at |
in that case, I have done such thing in past on one of my project let me try to find if I can get my hands on the command/script |
Here is a gil-reformatted repo. I used lint_history:
Pretty fast, so not a pb if it needs to be run again with the modifications discussed above. At some points we will need to unprotect the protected branches, force push the new history, protect again. It's best to do that when we have the least WIP PRs, since every contributors will need to rebase on the new history. A bit of git gymnastic... |
AppVeyor fails with |
GA is not covering stdcxx = 11 on msvc but definitely we can do something about it |
There is no such thing as plain C++11 for MSVC, only C11. VS 2015, 2017, 2019 default to C++14. Following @sdebionne suggestion, I'm going to get rid of AppVeyor - less is more :-) - #618 |
Do we need to pin the version of |
Bummer, I have just checked with my current project, switching from v10 to v12: formatting is a little different, some whitespaces added in a few files (3 out of hundreds)... |
Yes, that is known PITA of clang-format, from MongoDB experience:
I don't mind starting with the current latest. Hopefully, future releases of clang-format are going to receive less and less incompatibilities. |
I think, the only still open PRs that are going to be merged are the GSoC ones and some several of yours and @lpranam 's We may want to take the Boost release calendar into account: Summer release on the second Wednesday of August. IOW, either we do it soon or after the next release. |
@sdebionne I'm looking at the Did you use @lpranam 's https://github.com/sdebionne/gil-reformated/blob/d85dff7b77f8eacd8713a4692ffeeb43c89b3009/include/boost/gil/algorithm.hpp#L33-L37 displays the unbroken templates: template <typename ChannelPtr, typename ColorSpace>
struct planar_pixel_iterator;
template <typename Iterator> class memory_based_step_iterator;
template <typename StepIterator> class memory_based_2d_locator; while @lpranam 's configuration contains Line 26 in a3af622
|
This was my intention, let me check... |
Sorry for the delay, I accidentally overwrote my So I have reran the all thing from scratch, using the latest |
@sdebionne Thanks for dobule checking, it makes sense to me. Folks, what's your preference about #596 (comment) about scheduling the big reformat? /cc @lpranam @simmplecoder |
Uses the clang-format configuration provided in the latest commit of PR boostorg#596. Formatting is applied to test file and example file as well. I have made no changes whatsoever after using the clang-format.
i'd suggest first week after the release. |
So boost 1.77 is released now we can move ahead with refactoring now... |
I say YES! |
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see #596 (comment)
Description
provides .clang-format with the latest(clang-format 12) configuration
References
Tasklist