diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..3f0ad7ff0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,88 @@ +--- +Language: Cpp +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 78 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IndentCaseLabels: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... diff --git a/examples/getting_started_listing_01.cpp b/examples/getting_started_listing_01.cpp index d9ea67675..b7366ea7a 100644 --- a/examples/getting_started_listing_01.cpp +++ b/examples/getting_started_listing_01.cpp @@ -4,80 +4,75 @@ #include int main(int, char**) { - namespace bh = boost::histogram; - using namespace bh::literals; // enables _c suffix + namespace bh = boost::histogram; + using namespace bh::literals; // enables _c suffix - /* - create a static 1d-histogram with an axis that has 6 equidistant - bins on the real line from -1.0 to 2.0, and label it as "x" - */ - auto h = bh::make_static_histogram( - bh::axis::regular<>(6, -1.0, 2.0, "x") - ); + /* + create a static 1d-histogram with an axis that has 6 equidistant + bins on the real line from -1.0 to 2.0, and label it as "x" + */ + auto h = bh::make_static_histogram(bh::axis::regular<>(6, -1.0, 2.0, "x")); - // fill histogram with data, typically this happens in a loop - // STL algorithms are supported - auto data = { -0.5, 1.1, 0.3, 1.7 }; - std::for_each(data.begin(), data.end(), h); + // fill histogram with data, typically this happens in a loop + // STL algorithms are supported + auto data = {-0.5, 1.1, 0.3, 1.7}; + std::for_each(data.begin(), data.end(), h); - /* - a regular axis is a sequence of semi-open bins; extra under- and - overflow bins extend the axis in the default configuration - index : -1 0 1 2 3 4 5 6 - bin edge: -inf -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 inf - */ - h(-1.5); // put in underflow bin -1 - h(-1.0); // put in bin 0, bin interval is semi-open - h(2.0); // put in overflow bin 6, bin interval is semi-open - h(20.0); // put in overflow bin 6 + /* + a regular axis is a sequence of semi-open bins; extra under- and + overflow bins extend the axis in the default configuration + index : -1 0 1 2 3 4 5 6 + bin edge: -inf -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 inf + */ + h(-1.5); // put in underflow bin -1 + h(-1.0); // put in bin 0, bin interval is semi-open + h(2.0); // put in overflow bin 6, bin interval is semi-open + h(20.0); // put in overflow bin 6 - /* - do a weighted fill using bh::weight, a wrapper for any type, - which may appear at the beginning of the argument list - */ - h(bh::weight(1.0), 0.1); + /* + do a weighted fill using bh::weight, a wrapper for any type, + which may appear at the beginning of the argument list + */ + h(bh::weight(1.0), 0.1); - /* - iterate over bins with a fancy histogram iterator - - order in which bins are iterated over is an implementation detail - - iterator dereferences to histogram::element_type, which is defined by - its storage class; by default something with value() and - variance() methods; the first returns the - actual count, the second returns a variance estimate of the count - (see Rationale section for what this means) - - idx(N) method returns the index of the N-th axis - - bin(N_c) method returns current bin of N-th axis; the suffx _c turns - the argument into a compile-time number, which is needed to return - different `bin_type`s for different axes - - `bin_type` usually is a semi-open interval representing the bin, whose - edges can be accessed with methods `lower()` and `upper()`, but the - implementation depends on the axis, please look it up in the reference - */ - std::cout.setf(std::ios_base::fixed); - for (auto it = h.begin(); it != h.end(); ++it) { - const auto bin = it.bin(0_c); - std::cout << "bin " << it.idx(0) << " x in [" - << std::setprecision(1) - << std::setw(4) << bin.lower() << ", " - << std::setw(4) << bin.upper() << "): " - << std::setprecision(1) - << it->value() << " +/- " - << std::setprecision(3) << std::sqrt(it->variance()) - << std::endl; - } + /* + iterate over bins with a fancy histogram iterator + - order in which bins are iterated over is an implementation detail + - iterator dereferences to histogram::element_type, which is defined by + its storage class; by default something with value() and + variance() methods; the first returns the + actual count, the second returns a variance estimate of the count + (see Rationale section for what this means) + - idx(N) method returns the index of the N-th axis + - bin(N_c) method returns current bin of N-th axis; the suffx _c turns + the argument into a compile-time number, which is needed to return + different `bin_type`s for different axes + - `bin_type` usually is a semi-open interval representing the bin, whose + edges can be accessed with methods `lower()` and `upper()`, but the + implementation depends on the axis, please look it up in the reference + */ + std::cout.setf(std::ios_base::fixed); + for (auto it = h.begin(); it != h.end(); ++it) { + const auto bin = it.bin(0_c); + std::cout << "bin " << it.idx(0) << " x in [" << std::setprecision(1) + << std::setw(4) << bin.lower() << ", " << std::setw(4) + << bin.upper() << "): " << std::setprecision(1) << it->value() + << " +/- " << std::setprecision(3) << std::sqrt(it->variance()) + << std::endl; + } - /* program output: (note that under- and overflow bins appear at the end) + /* program output: (note that under- and overflow bins appear at the end) - bin 0 x in [-1.0, -0.5): 1 +/- 1 - bin 1 x in [-0.5, 0.0): 0 +/- 0 - bin 2 x in [ 0.0, 0.5): 1 +/- 1 - bin 3 x in [ 0.5, 1.0): 0 +/- 0 - bin 4 x in [ 1.0, 1.5): 0 +/- 0 - bin 5 x in [ 1.5, 2.0): 0 +/- 0 - bin 6 x in [ 2.0, inf): 2 +/- 1.41421 - bin -1 x in [-inf, -1): 1 +/- 1 + bin 0 x in [-1.0, -0.5): 1 +/- 1 + bin 1 x in [-0.5, 0.0): 0 +/- 0 + bin 2 x in [ 0.0, 0.5): 1 +/- 1 + bin 3 x in [ 0.5, 1.0): 0 +/- 0 + bin 4 x in [ 1.0, 1.5): 0 +/- 0 + bin 5 x in [ 1.5, 2.0): 0 +/- 0 + bin 6 x in [ 2.0, inf): 2 +/- 1.41421 + bin -1 x in [-inf, -1): 1 +/- 1 - */ + */ } //] diff --git a/examples/getting_started_listing_02.cpp b/examples/getting_started_listing_02.cpp index bfb32e475..4e6518650 100644 --- a/examples/getting_started_listing_02.cpp +++ b/examples/getting_started_listing_02.cpp @@ -10,42 +10,42 @@ namespace br = boost::random; namespace bh = boost::histogram; int main() { - /* - create a dynamic histogram with the factory `make_dynamic_histogram` - - axis can be passed directly just like for `make_static_histogram` - - in addition, the factory also accepts iterators over a sequence of - axis::any, the polymorphic type that can hold concrete axis types - */ - std::vector axes; - axes.emplace_back(bh::axis::category({"red", "blue"})); - axes.emplace_back(bh::axis::regular<>(5, -5, 5, "x")); - axes.emplace_back(bh::axis::regular<>(5, -5, 5, "y")); - auto h = bh::make_dynamic_histogram(axes.begin(), axes.end()); + /* + create a dynamic histogram with the factory `make_dynamic_histogram` + - axis can be passed directly just like for `make_static_histogram` + - in addition, the factory also accepts iterators over a sequence of + axis::any, the polymorphic type that can hold concrete axis types + */ + std::vector axes; + axes.emplace_back(bh::axis::category({"red", "blue"})); + axes.emplace_back(bh::axis::regular<>(5, -5, 5, "x")); + axes.emplace_back(bh::axis::regular<>(5, -5, 5, "y")); + auto h = bh::make_dynamic_histogram(axes.begin(), axes.end()); - // fill histogram with random numbers - br::mt19937 gen; - br::normal_distribution<> norm; - for (int i = 0; i < 1000; ++i) - h(i % 2 ? "red" : "blue", norm(gen), norm(gen)); + // fill histogram with random numbers + br::mt19937 gen; + br::normal_distribution<> norm; + for (int i = 0; i < 1000; ++i) + h(i % 2 ? "red" : "blue", norm(gen), norm(gen)); - /* - print dynamic histogram by iterating over bins - - for most axis types, the for loop looks just like for a static - histogram, except that we can pass runtime numbers, too - - if the [bin type] of the axis is not convertible to a - double interval, one needs to cast axis::any before looping; - this is here the case for the category axis - */ - using cas = bh::axis::category; - for (auto cbin : bh::axis::cast(h.axis(0))) { - std::printf("%s\n", cbin.value().c_str()); - for (auto ybin : h.axis(2)) { // rows - for (auto xbin : h.axis(1)) { // columns - std::printf("%3.0f ", h.at(cbin, xbin, ybin).value()); - } - std::printf("\n"); - } + /* + print dynamic histogram by iterating over bins + - for most axis types, the for loop looks just like for a static + histogram, except that we can pass runtime numbers, too + - if the [bin type] of the axis is not convertible to a + double interval, one needs to cast axis::any before looping; + this is here the case for the category axis + */ + using cas = bh::axis::category; + for (auto cbin : bh::axis::cast(h.axis(0))) { + std::printf("%s\n", cbin.value().c_str()); + for (auto ybin : h.axis(2)) { // rows + for (auto xbin : h.axis(1)) { // columns + std::printf("%3.0f ", h.at(cbin, xbin, ybin).value()); + } + std::printf("\n"); } + } } //] diff --git a/examples/guide_access_bin_counts.cpp b/examples/guide_access_bin_counts.cpp index 7855fb174..324fb66e2 100644 --- a/examples/guide_access_bin_counts.cpp +++ b/examples/guide_access_bin_counts.cpp @@ -7,50 +7,43 @@ namespace bh = boost::histogram; int main() { - // make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins) - auto h = bh::make_static_histogram( - bh::axis::regular<>(2, -1, 1), - bh::axis::regular<>(2, 2, 4) - ); - - h(bh::weight(1), -0.5, 2.5); // bin index 0, 0 - h(bh::weight(2), -0.5, 3.5); // bin index 0, 1 - h(bh::weight(3), 0.5, 2.5); // bin index 1, 0 - h(bh::weight(4), 0.5, 3.5); // bin index 1, 1 - - // access count value, number of indices must match number of axes - std::cout << h.at(0, 0).value() << " " - << h.at(0, 1).value() << " " - << h.at(1, 0).value() << " " - << h.at(1, 1).value() - << std::endl; - - // prints: 1 2 3 4 - - // access count variance, number of indices must match number of axes - std::cout << h.at(0, 0).variance() << " " - << h.at(0, 1).variance() << " " - << h.at(1, 0).variance() << " " - << h.at(1, 1).variance() - << std::endl; - // prints: 1 4 9 16 - - // you can also make a copy of the type that holds the bin count - auto c11 = h.at(1, 1); - std::cout << c11.value() << " " << c11.variance() << std::endl; - // prints: 4 16 - - // histogram also supports access via container; using a container of - // wrong size trips an assertion in debug mode - auto idx = {0, 1}; - std::cout << h.at(idx).value() << std::endl; - // prints: 2 - - // histogram also provides extended iterators - auto sum = std::accumulate(h.begin(), h.end(), - typename decltype(h)::element_type(0)); - std::cout << sum.value() << " " << sum.variance() << std::endl; - // prints: 10 30 + // make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins) + auto h = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1), + bh::axis::regular<>(2, 2, 4)); + + h(bh::weight(1), -0.5, 2.5); // bin index 0, 0 + h(bh::weight(2), -0.5, 3.5); // bin index 0, 1 + h(bh::weight(3), 0.5, 2.5); // bin index 1, 0 + h(bh::weight(4), 0.5, 3.5); // bin index 1, 1 + + // access count value, number of indices must match number of axes + std::cout << h.at(0, 0).value() << " " << h.at(0, 1).value() << " " + << h.at(1, 0).value() << " " << h.at(1, 1).value() << std::endl; + + // prints: 1 2 3 4 + + // access count variance, number of indices must match number of axes + std::cout << h.at(0, 0).variance() << " " << h.at(0, 1).variance() << " " + << h.at(1, 0).variance() << " " << h.at(1, 1).variance() + << std::endl; + // prints: 1 4 9 16 + + // you can also make a copy of the type that holds the bin count + auto c11 = h.at(1, 1); + std::cout << c11.value() << " " << c11.variance() << std::endl; + // prints: 4 16 + + // histogram also supports access via container; using a container of + // wrong size trips an assertion in debug mode + auto idx = {0, 1}; + std::cout << h.at(idx).value() << std::endl; + // prints: 2 + + // histogram also provides extended iterators + auto sum = std::accumulate(h.begin(), h.end(), + typename decltype(h)::element_type(0)); + std::cout << sum.value() << " " << sum.variance() << std::endl; + // prints: 10 30 } //] diff --git a/examples/guide_axis_with_labels.cpp b/examples/guide_axis_with_labels.cpp index e2fbfcdac..2fe0dabc1 100644 --- a/examples/guide_axis_with_labels.cpp +++ b/examples/guide_axis_with_labels.cpp @@ -5,13 +5,12 @@ namespace bh = boost::histogram; int main() { - // create a 2d-histogram with an "age" and an "income" axis - auto h = bh::make_static_histogram( - bh::axis::regular<>(20, 0, 100, "age in years"), - bh::axis::regular<>(20, 0, 100, "yearly income in $1000") - ); + // create a 2d-histogram with an "age" and an "income" axis + auto h = bh::make_static_histogram( + bh::axis::regular<>(20, 0, 100, "age in years"), + bh::axis::regular<>(20, 0, 100, "yearly income in $1000")); - // do something with h + // do something with h } //] diff --git a/examples/guide_axis_with_uoflow_off.cpp b/examples/guide_axis_with_uoflow_off.cpp index 786c61ea4..a7b70e95e 100644 --- a/examples/guide_axis_with_uoflow_off.cpp +++ b/examples/guide_axis_with_uoflow_off.cpp @@ -5,10 +5,11 @@ namespace bh = boost::histogram; int main() { - // create a 1d-histogram for dice throws with integer values from 1 to 6 - auto h = bh::make_static_histogram(bh::axis::integer<>(1, 7, "eyes", bh::axis::uoflow::off)); + // create a 1d-histogram for dice throws with integer values from 1 to 6 + auto h = bh::make_static_histogram( + bh::axis::integer<>(1, 7, "eyes", bh::axis::uoflow::off)); - // do something with h + // do something with h } //] diff --git a/examples/guide_custom_axis.cpp b/examples/guide_custom_axis.cpp index 1f1402788..f037286ee 100644 --- a/examples/guide_custom_axis.cpp +++ b/examples/guide_custom_axis.cpp @@ -7,36 +7,33 @@ namespace bh = boost::histogram; // custom axis, which adapts builtin integer axis struct custom_axis : public bh::axis::integer<> { - using value_type = const char*; // type that is fed to the axis + using value_type = const char*; // type that is fed to the axis - using integer::integer; // inherit ctors of base + using integer::integer; // inherit ctors of base - // the customization point - // - accept const char* and convert to int - // - then call index method of base class - int index(value_type s) const { - return integer::index(std::atoi(s)); - } + // the customization point + // - accept const char* and convert to int + // - then call index method of base class + int index(value_type s) const { return integer::index(std::atoi(s)); } }; int main() { - auto h = bh::make_static_histogram(custom_axis(0, 3)); - h("-10"); - h("0"); - h("1"); - h("9"); - - for (auto xi : h.axis()) { - std::cout << "bin " << xi.idx() << " [" << xi.lower() << ", " - << xi.upper() << ") " << h.at(xi).value() - << std::endl; - } - - /* prints: - bin 0 [0, 1) 1 - bin 1 [1, 2] 1 - bin 2 [2, 3] 0 - */ + auto h = bh::make_static_histogram(custom_axis(0, 3)); + h("-10"); + h("0"); + h("1"); + h("9"); + + for (auto xi : h.axis()) { + std::cout << "bin " << xi.idx() << " [" << xi.lower() << ", " + << xi.upper() << ") " << h.at(xi).value() << std::endl; + } + + /* prints: + bin 0 [0, 1) 1 + bin 1 [1, 2] 1 + bin 2 [2, 3] 0 + */ } //] diff --git a/examples/guide_custom_storage.cpp b/examples/guide_custom_storage.cpp index aaa4a0004..0e64179b6 100644 --- a/examples/guide_custom_storage.cpp +++ b/examples/guide_custom_storage.cpp @@ -6,12 +6,11 @@ namespace bh = boost::histogram; int main() { - // create static histogram with array_storage, using int as counter type - auto h = bh::make_static_histogram_with>( - bh::axis::regular<>(10, 0, 1) - ); + // create static histogram with array_storage, using int as counter type + auto h = bh::make_static_histogram_with>( + bh::axis::regular<>(10, 0, 1)); - // do something with h + // do something with h } //] diff --git a/examples/guide_fill_histogram.cpp b/examples/guide_fill_histogram.cpp index 0d4e247e0..68c15c9d3 100644 --- a/examples/guide_fill_histogram.cpp +++ b/examples/guide_fill_histogram.cpp @@ -1,38 +1,37 @@ //[ guide_fill_histogram #include -#include #include +#include namespace bh = boost::histogram; int main() { - auto h = bh::make_static_histogram(bh::axis::integer<>(0, 4), - bh::axis::regular<>(10, 0, 5)); + auto h = bh::make_static_histogram(bh::axis::integer<>(0, 4), + bh::axis::regular<>(10, 0, 5)); - // fill histogram, number of arguments must be equal to number of axes - h(0, 1.1); // increases bin counter by one - h(bh::weight(2), 3, 3.4); // increase bin counter by 2 instead of 1 + // fill histogram, number of arguments must be equal to number of axes + h(0, 1.1); // increases bin counter by one + h(bh::weight(2), 3, 3.4); // increase bin counter by 2 instead of 1 - // histogram also supports fills from a container of values; a container - // of wrong size trips an assertion in debug mode - auto xy1 = std::make_pair(4, 3.1); - h(xy1); - auto xy2 = std::vector({3.0, 4.9}); - h(xy2); + // histogram also supports fills from a container of values; a container + // of wrong size trips an assertion in debug mode + auto xy1 = std::make_pair(4, 3.1); + h(xy1); + auto xy2 = std::vector({3.0, 4.9}); + h(xy2); - // functional-style processing is also supported - std::vector> input_data{ - {0, 1.2}, {2, 3.4}, {4, 5.6} - }; - // Note that std::for_each takes the functor by value, thus it makes a - // potentially expensive copy of your histogram. Passing freshly created - // histograms is ok, though, because of return-value-optimization - auto h2 = std::for_each(input_data.begin(), input_data.end(), - bh::make_static_histogram( - bh::axis::integer<>(0, 4), - bh::axis::regular<>(10, 0, 5))); - // h is filled + // functional-style processing is also supported + std::vector> input_data{ + {0, 1.2}, {2, 3.4}, {4, 5.6}}; + // Note that std::for_each takes the functor by value, thus it makes a + // potentially expensive copy of your histogram. Passing freshly created + // histograms is ok, though, because of return-value-optimization + auto h2 = + std::for_each(input_data.begin(), input_data.end(), + bh::make_static_histogram(bh::axis::integer<>(0, 4), + bh::axis::regular<>(10, 0, 5))); + // h is filled } //] diff --git a/examples/guide_histogram_operators.cpp b/examples/guide_histogram_operators.cpp index 5f49d5df4..1d0acb92f 100644 --- a/examples/guide_histogram_operators.cpp +++ b/examples/guide_histogram_operators.cpp @@ -6,52 +6,52 @@ namespace bh = boost::histogram; int main() { - // make two histograms - auto h1 = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); - auto h2 = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); - - h1(-0.5); // counts are: 1 0 - h2(0.5); // counts are: 0 1 - - // add them - auto h3 = h1; - h3 += h2; // counts are: 1 1 - - // adding multiple histograms at once is efficient and does not create - // superfluous temporaries since operator+ functions are overloaded to - // accept and return rvalue references where possible - auto h4 = h1 + h2 + h3; // counts are: 2 2 - - std::cout << h4.at(0).value() << " " << h4.at(1).value() << std::endl; - // prints: 2 2 - - // multiply by number - h4 *= 2; // counts are: 4 4 - - // divide by number - auto h5 = h4 / 4; // counts are: 1 1 - - std::cout << h5.at(0).value() << " " << h5.at(1).value() << std::endl; - // prints: 1 1 - - // compare histograms - std::cout << (h4 == 4 * h5) << " " << (h4 != h5) << std::endl; - // prints: 1 1 - - // note: special effect of multiplication on counter variance - auto h = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); - h(-0.5); // counts are: 1 0 - std::cout << "value " << (2 * h).at(0).value() - << " " << (h + h).at(0).value() << "\n" - << "variance " << (2 * h).at(0).variance() - << " " << (h + h).at(0).variance() << std::endl; - // equality operator also checks variances, so the statement is false - std::cout << (h + h == 2 * h) << std::endl; - /* prints: - value 2 2 - variance 4 2 - 0 - */ + // make two histograms + auto h1 = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); + auto h2 = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); + + h1(-0.5); // counts are: 1 0 + h2(0.5); // counts are: 0 1 + + // add them + auto h3 = h1; + h3 += h2; // counts are: 1 1 + + // adding multiple histograms at once is efficient and does not create + // superfluous temporaries since operator+ functions are overloaded to + // accept and return rvalue references where possible + auto h4 = h1 + h2 + h3; // counts are: 2 2 + + std::cout << h4.at(0).value() << " " << h4.at(1).value() << std::endl; + // prints: 2 2 + + // multiply by number + h4 *= 2; // counts are: 4 4 + + // divide by number + auto h5 = h4 / 4; // counts are: 1 1 + + std::cout << h5.at(0).value() << " " << h5.at(1).value() << std::endl; + // prints: 1 1 + + // compare histograms + std::cout << (h4 == 4 * h5) << " " << (h4 != h5) << std::endl; + // prints: 1 1 + + // note: special effect of multiplication on counter variance + auto h = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1)); + h(-0.5); // counts are: 1 0 + std::cout << "value " << (2 * h).at(0).value() << " " + << (h + h).at(0).value() << "\n" + << "variance " << (2 * h).at(0).variance() << " " + << (h + h).at(0).variance() << std::endl; + // equality operator also checks variances, so the statement is false + std::cout << (h + h == 2 * h) << std::endl; + /* prints: + value 2 2 + variance 4 2 + 0 + */ } //] diff --git a/examples/guide_histogram_reduction.cpp b/examples/guide_histogram_reduction.cpp index 498d08b69..43670ebcf 100644 --- a/examples/guide_histogram_reduction.cpp +++ b/examples/guide_histogram_reduction.cpp @@ -7,56 +7,51 @@ namespace bh = boost::histogram; // example of a generic function for histograms, this one sums all entries template -typename bh::histogram::element_type sum(const bh::histogram& h) { - auto result = typename bh::histogram::element_type(0); - for (auto x : h) - result += x; - return result; +typename bh::histogram::element_type sum( + const bh::histogram& h) { + auto result = typename bh::histogram::element_type(0); + for (auto x : h) result += x; + return result; } int main() { - using namespace bh::literals; // enables _c suffix - - // make a 2d histogram - auto h = bh::make_static_histogram(bh::axis::regular<>(3, -1, 1), - bh::axis::integer<>(0, 4)); - - h(-0.9, 0); - h(0.9, 3); - h(0.1, 2); - - auto hr0 = h.reduce_to(0_c); // keep only first axis - auto hr1 = h.reduce_to(1_c); // keep only second axis - - /* - reduce does not remove counts; returned histograms are summed over - the removed axes, so h, hr0, and hr1 have same number of total counts - */ - std::cout << sum(h).value() << " " - << sum(hr0).value() << " " - << sum(hr1).value() << std::endl; - // prints: 3 3 3 - - for (auto yi : h.axis(1_c)) { - for (auto xi : h.axis(0_c)) { - std::cout << h.at(xi, yi).value() << " "; - } - std::cout << std::endl; - } - // prints: 1 0 0 - // 0 0 0 - // 0 1 0 - // 0 0 1 - - for (auto xi : hr0.axis()) - std::cout << hr0.at(xi).value() << " "; - std::cout << std::endl; - // prints: 1 1 1 + using namespace bh::literals; // enables _c suffix + + // make a 2d histogram + auto h = bh::make_static_histogram(bh::axis::regular<>(3, -1, 1), + bh::axis::integer<>(0, 4)); + + h(-0.9, 0); + h(0.9, 3); + h(0.1, 2); + + auto hr0 = h.reduce_to(0_c); // keep only first axis + auto hr1 = h.reduce_to(1_c); // keep only second axis + + /* + reduce does not remove counts; returned histograms are summed over + the removed axes, so h, hr0, and hr1 have same number of total counts + */ + std::cout << sum(h).value() << " " << sum(hr0).value() << " " + << sum(hr1).value() << std::endl; + // prints: 3 3 3 - for (auto yi : hr1.axis()) - std::cout << hr1.at(yi).value() << " "; + for (auto yi : h.axis(1_c)) { + for (auto xi : h.axis(0_c)) { std::cout << h.at(xi, yi).value() << " "; } std::cout << std::endl; - // prints: 1 0 1 1 + } + // prints: 1 0 0 + // 0 0 0 + // 0 1 0 + // 0 0 1 + + for (auto xi : hr0.axis()) std::cout << hr0.at(xi).value() << " "; + std::cout << std::endl; + // prints: 1 1 1 + + for (auto yi : hr1.axis()) std::cout << hr1.at(yi).value() << " "; + std::cout << std::endl; + // prints: 1 0 1 1 } //] diff --git a/examples/guide_histogram_serialization.cpp b/examples/guide_histogram_serialization.cpp index 754297bcf..7f6faffec 100644 --- a/examples/guide_histogram_serialization.cpp +++ b/examples/guide_histogram_serialization.cpp @@ -1,42 +1,42 @@ //[ guide_histogram_serialization -#include -#include // includes serialization code #include #include +#include +#include // includes serialization code #include namespace bh = boost::histogram; int main() { - auto a = bh::make_static_histogram(bh::axis::regular<>(3, -1, 1, "r"), - bh::axis::integer<>(0, 2, "i")); - a(0.5, 1); - - std::string buf; // holds persistent representation - - // store histogram - { - std::ostringstream os; - boost::archive::text_oarchive oa(os); - oa << a; - buf = os.str(); - } - - auto b = decltype(a)(); // create a default-constructed second histogram - - std::cout << "before restore " << (a == b) << std::endl; - // prints: before restore 0 - - // load histogram - { - std::istringstream is(buf); - boost::archive::text_iarchive ia(is); - ia >> b; - } - - std::cout << "after restore " << (a == b) << std::endl; - // prints: after restore 1 + auto a = bh::make_static_histogram(bh::axis::regular<>(3, -1, 1, "r"), + bh::axis::integer<>(0, 2, "i")); + a(0.5, 1); + + std::string buf; // holds persistent representation + + // store histogram + { + std::ostringstream os; + boost::archive::text_oarchive oa(os); + oa << a; + buf = os.str(); + } + + auto b = decltype(a)(); // create a default-constructed second histogram + + std::cout << "before restore " << (a == b) << std::endl; + // prints: before restore 0 + + // load histogram + { + std::istringstream is(buf); + boost::archive::text_iarchive ia(is); + ia >> b; + } + + std::cout << "after restore " << (a == b) << std::endl; + // prints: after restore 1 } //] diff --git a/examples/guide_histogram_streaming.cpp b/examples/guide_histogram_streaming.cpp index fb357499b..e49267e50 100644 --- a/examples/guide_histogram_streaming.cpp +++ b/examples/guide_histogram_streaming.cpp @@ -7,33 +7,32 @@ namespace bh = boost::histogram; int main() { - namespace axis = boost::histogram::axis; + namespace axis = boost::histogram::axis; - enum { A, B, C }; + enum { A, B, C }; - auto h = bh::make_static_histogram( - axis::regular<>(2, -1, 1, "regular1", axis::uoflow::off), - axis::regular(2, 1, 10, "regular2"), - axis::circular<>(4, 0.1, 1.0, "polar"), - axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off), - axis::category<>({A, B, C}, "category"), - axis::integer<>(-1, 1, "integer", axis::uoflow::off) - ); + auto h = bh::make_static_histogram( + axis::regular<>(2, -1, 1, "regular1", axis::uoflow::off), + axis::regular(2, 1, 10, "regular2"), + axis::circular<>(4, 0.1, 1.0, "polar"), + axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off), + axis::category<>({A, B, C}, "category"), + axis::integer<>(-1, 1, "integer", axis::uoflow::off)); - std::cout << h << std::endl; + std::cout << h << std::endl; - /* prints: + /* prints: - histogram( - regular(2, -1, 1, label='regular1', uoflow=False), - regular_log(2, 1, 10, label='regular2'), - circular(4, phase=0.1, perimeter=1, label='polar'), - variable(-1, 0, 1, label='variable', uoflow=False), - category(0, 1, 2, label='category'), - integer(-1, 1, label='integer', uoflow=False), - ) + histogram( + regular(2, -1, 1, label='regular1', uoflow=False), + regular_log(2, 1, 10, label='regular2'), + circular(4, phase=0.1, perimeter=1, label='polar'), + variable(-1, 0, 1, label='variable', uoflow=False), + category(0, 1, 2, label='category'), + integer(-1, 1, label='integer', uoflow=False), + ) - */ + */ } //] diff --git a/examples/guide_make_dynamic_histogram.cpp b/examples/guide_make_dynamic_histogram.cpp index 39cfb7c43..2503fdee1 100644 --- a/examples/guide_make_dynamic_histogram.cpp +++ b/examples/guide_make_dynamic_histogram.cpp @@ -6,15 +6,15 @@ namespace bh = boost::histogram; int main() { - // create vector of axes, axis::any is a polymorphic axis type - auto v = std::vector(); - v.push_back(bh::axis::regular<>(100, -1, 1)); - v.push_back(bh::axis::integer<>(1, 7)); + // create vector of axes, axis::any is a polymorphic axis type + auto v = std::vector(); + v.push_back(bh::axis::regular<>(100, -1, 1)); + v.push_back(bh::axis::integer<>(1, 7)); - // create dynamic histogram (make_static_histogram be used with iterators) - auto h = bh::make_dynamic_histogram(v.begin(), v.end()); + // create dynamic histogram (make_static_histogram be used with iterators) + auto h = bh::make_dynamic_histogram(v.begin(), v.end()); - // do something with h + // do something with h } //] diff --git a/examples/guide_make_static_histogram.cpp b/examples/guide_make_static_histogram.cpp index 6e3538133..35ac04683 100644 --- a/examples/guide_make_static_histogram.cpp +++ b/examples/guide_make_static_histogram.cpp @@ -5,14 +5,14 @@ namespace bh = boost::histogram; int main() { - /* - create a 1d-histogram in default configuration which - covers the real line from -1 to 1 in 100 bins, the same - call with `make_dynamic_histogram` would also work - */ - auto h = bh::make_static_histogram(bh::axis::regular<>(100, -1, 1)); + /* + create a 1d-histogram in default configuration which + covers the real line from -1 to 1 in 100 bins, the same + call with `make_dynamic_histogram` would also work + */ + auto h = bh::make_static_histogram(bh::axis::regular<>(100, -1, 1)); - // do something with h + // do something with h } //] diff --git a/examples/guide_mixed_cpp_python.cpp b/examples/guide_mixed_cpp_python.cpp index 9662b63a5..a2c05ebc3 100644 --- a/examples/guide_mixed_cpp_python.cpp +++ b/examples/guide_mixed_cpp_python.cpp @@ -1,7 +1,7 @@ //[ guide_mixed_cpp_python_part_cpp -#include #include +#include namespace bh = boost::histogram; namespace bp = boost::python; @@ -9,13 +9,10 @@ namespace bp = boost::python; // function that runs in C++ and accepts reference to dynamic histogram void process(bh::dynamic_histogram<>& h) { // fill histogram, in reality this would be arbitrarily complex code - for (int i = 0; i < 4; ++i) - h(0.25 * i, i); + for (int i = 0; i < 4; ++i) h(0.25 * i, i); } // a minimal Python module, which exposes the process function to Python -BOOST_PYTHON_MODULE(cpp_filler) { - bp::def("process", process); -} +BOOST_PYTHON_MODULE(cpp_filler) { bp::def("process", process); } //] diff --git a/include/boost/histogram/arithmetic_operators.hpp b/include/boost/histogram/arithmetic_operators.hpp index aed12d426..1aa9d1e5d 100644 --- a/include/boost/histogram/arithmetic_operators.hpp +++ b/include/boost/histogram/arithmetic_operators.hpp @@ -13,67 +13,68 @@ namespace boost { namespace histogram { template -histogram &&operator+(histogram &&a, - const histogram &b) { +histogram&& operator+(histogram&& a, + const histogram& b) { a += b; return std::move(a); } template -histogram &&operator+(histogram &&a, histogram &&b) { +histogram&& operator+(histogram&& a, + histogram&& b) { a += b; return std::move(a); } template -histogram &&operator+(const histogram &a, - histogram &&b) { +histogram&& operator+(const histogram& a, + histogram&& b) { b += a; return std::move(b); } template -histogram operator+(const histogram &a, - const histogram &b) { +histogram operator+(const histogram& a, + const histogram& b) { histogram r(a); r += b; return r; } template -histogram &&operator*(histogram &&a, const double x) { +histogram&& operator*(histogram&& a, const double x) { a *= x; return std::move(a); } template -histogram &&operator*(const double x, histogram &&b) { +histogram&& operator*(const double x, histogram&& b) { b *= x; return std::move(b); } template -histogram operator*(const histogram &a, const double x) { +histogram operator*(const histogram& a, const double x) { auto r = a; r *= x; return r; } template -histogram operator*(const double x, const histogram &b) { +histogram operator*(const double x, const histogram& b) { auto r = b; r *= x; return r; } template -histogram &&operator/(histogram &&a, const double x) { +histogram&& operator/(histogram&& a, const double x) { a /= x; return std::move(a); } template -histogram operator/(const histogram &a, const double x) { +histogram operator/(const histogram& a, const double x) { auto r = a; r /= x; return r; diff --git a/include/boost/histogram/axis/any.hpp b/include/boost/histogram/axis/any.hpp index de08c3bc7..e5a59becb 100644 --- a/include/boost/histogram/axis/any.hpp +++ b/include/boost/histogram/axis/any.hpp @@ -33,19 +33,29 @@ namespace axis { namespace detail { struct size_visitor : public static_visitor { - template int operator()(const A &a) const { return a.size(); } + template + int operator()(const A& a) const { + return a.size(); + } }; struct shape_visitor : public static_visitor { - template int operator()(const A &a) const { return a.shape(); } + template + int operator()(const A& a) const { + return a.shape(); + } }; struct uoflow_visitor : public static_visitor { - template bool operator()(const A &a) const { return a.uoflow(); } + template + bool operator()(const A& a) const { + return a.uoflow(); + } }; struct get_label_visitor : public static_visitor { - template ::boost::string_view operator()(const A &a) const { + template + ::boost::string_view operator()(const A& a) const { return a.label(); } }; @@ -53,19 +63,25 @@ struct get_label_visitor : public static_visitor { struct set_label_visitor : public static_visitor { const ::boost::string_view label; set_label_visitor(const ::boost::string_view x) : label(x) {} - template void operator()(A &a) const { a.label(label); } + template + void operator()(A& a) const { + a.label(label); + } }; struct index_visitor : public static_visitor { const double x; explicit index_visitor(const double arg) : x(arg) {} - template int operator()(const Axis &a) const { + template + int operator()(const Axis& a) const { return impl(std::is_convertible(), a); } - template int impl(std::true_type, const Axis &a) const { + template + int impl(std::true_type, const Axis& a) const { return a.index(x); } - template int impl(std::false_type, const Axis &) const { + template + int impl(std::false_type, const Axis&) const { throw std::runtime_error(::boost::histogram::detail::cat( "cannot convert double to value_type ", boost::typeindex::type_id().pretty_name(), @@ -76,7 +92,8 @@ struct index_visitor : public static_visitor { struct lower_visitor : public static_visitor { int idx; lower_visitor(int i) : idx(i) {} - template double operator()(const Axis &a) const { + template + double operator()(const Axis& a) const { return impl( std::integral_constant< bool, @@ -85,10 +102,12 @@ struct lower_visitor : public static_visitor { interval_view>::value)>(), a); } - template double impl(std::true_type, const Axis &a) const { + template + double impl(std::true_type, const Axis& a) const { return a.lower(idx); } - template double impl(std::false_type, const Axis &) const { + template + double impl(std::false_type, const Axis&) const { throw std::runtime_error(::boost::histogram::detail::cat( "cannot use ", boost::typeindex::type_id().pretty_name(), " with generic boost::histogram::axis::any interface, use" @@ -98,25 +117,32 @@ struct lower_visitor : public static_visitor { struct bicmp_visitor : public static_visitor { template - bool operator()(const T &, const U &) const { + bool operator()(const T&, const U&) const { return false; } - template bool operator()(const T &a, const T &b) const { + template + bool operator()(const T& a, const T& b) const { return a == b; } }; -template struct assign_visitor : public static_visitor { - T &t; - assign_visitor(T &tt) : t(tt) {} - template void operator()(const U &u) const { +template +struct assign_visitor : public static_visitor { + T& t; + assign_visitor(T& tt) : t(tt) {} + template + void operator()(const U& u) const { impl(mp11::mp_contains(), u); } - template void impl(mp11::mp_true, const U &u) const { t = u; } + template + void impl(mp11::mp_true, const U& u) const { + t = u; + } - template void impl(mp11::mp_false, const U &) const { + template + void impl(mp11::mp_false, const U&) const { throw std::invalid_argument(::boost::histogram::detail::cat( "argument ", boost::typeindex::type_id().pretty_name(), " is not a bounded type of ", @@ -127,7 +153,8 @@ template struct assign_visitor : public static_visitor { } // namespace detail /// Polymorphic axis type -template class any : public ::boost::variant { +template +class any : public ::boost::variant { using base_type = ::boost::variant; public: @@ -140,29 +167,32 @@ template class any : public ::boost::variant { private: template using requires_bounded_type = mp11::mp_if< - mp11::mp_contains>, void>; + mp11::mp_contains>, + void>; public: any() = default; - any(const any &) = default; - any &operator=(const any &) = default; - any(any &&) = default; - any &operator=(any &&) = default; + any(const any&) = default; + any& operator=(const any&) = default; + any(any&&) = default; + any& operator=(any&&) = default; template > - any(T &&t) : base_type(std::forward(t)) {} + any(T&& t) : base_type(std::forward(t)) {} template > - any &operator=(T &&t) { + any& operator=(T&& t) { base_type::operator=(std::forward(t)); return *this; } - template any(const any &u) { + template + any(const any& u) { ::boost::apply_visitor(detail::assign_visitor(*this), u); } - template any &operator=(const any &u) { + template + any& operator=(const any& u) { ::boost::apply_visitor(detail::assign_visitor(*this), u); return *this; } @@ -200,22 +230,24 @@ template class any : public ::boost::variant { bin_type operator[](const int idx) const { return bin_type(idx, *this); } - bool operator==(const any &rhs) const { - return base_type::operator==(static_cast(rhs)); + bool operator==(const any& rhs) const { + return base_type::operator==(static_cast(rhs)); } - template bool operator==(const any &u) const { + template + bool operator==(const any& u) const { return ::boost::apply_visitor(detail::bicmp_visitor(), *this, u); } template > - bool operator==(const T &t) const { + bool operator==(const T& t) const { // variant::operator==(T) is implemented, but only to fail, cannot use it auto tp = ::boost::get<::boost::histogram::detail::rm_cv_ref>(this); return tp && *tp == t; } - template bool operator!=(T &&t) const { + template + bool operator!=(T&& t) const { return !operator==(std::forward(t)); } @@ -230,34 +262,36 @@ template class any : public ::boost::variant { private: friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; // dynamic casts template -typename std::add_lvalue_reference::type cast(any &any) { +typename std::add_lvalue_reference::type cast(any& any) { return get(any); } template -const typename std::add_lvalue_reference::type cast(const any &any) { +const typename std::add_lvalue_reference::type cast( + const any& any) { return get(any); } template -typename std::add_pointer::type cast(any *any) { +typename std::add_pointer::type cast(any* any) { return get(&any); } template -const typename std::add_pointer::type cast(const any *any) { +const typename std::add_pointer::type cast(const any* any) { return get(&any); } // pass-through for generic programming, to keep code workgin when // you switch from dynamic to static histogram template -auto cast(U &&u) -> decltype(std::forward(u)) { +auto cast(U&& u) -> decltype(std::forward(u)) { return std::forward(u); } diff --git a/include/boost/histogram/axis/interval_view.hpp b/include/boost/histogram/axis/interval_view.hpp index e7c7f11d4..ecea5329f 100644 --- a/include/boost/histogram/axis/interval_view.hpp +++ b/include/boost/histogram/axis/interval_view.hpp @@ -14,29 +14,32 @@ namespace boost { namespace histogram { namespace axis { -template class interval_view { +template +class interval_view { public: - interval_view(int idx, const Axis &axis) : idx_(idx), axis_(axis) {} + interval_view(int idx, const Axis& axis) : idx_(idx), axis_(axis) {} - interval_view(const interval_view &) = default; - interval_view &operator=(const interval_view &) = default; - interval_view(interval_view &&) = default; - interval_view &operator=(interval_view &&) = default; + interval_view(const interval_view&) = default; + interval_view& operator=(const interval_view&) = default; + interval_view(interval_view&&) = default; + interval_view& operator=(interval_view&&) = default; int idx() const noexcept { return idx_; } - auto lower() const noexcept -> decltype(std::declval().lower(0)) { + auto lower() const noexcept -> decltype(std::declval().lower(0)) { return axis_.lower(idx_); } - auto upper() const noexcept -> decltype(std::declval().lower(0)) { + auto upper() const noexcept -> decltype(std::declval().lower(0)) { return axis_.lower(idx_ + 1); } - typename Axis::value_type width() const noexcept { return upper() - lower(); } + typename Axis::value_type width() const noexcept { + return upper() - lower(); + } - bool operator==(const interval_view &rhs) const noexcept { + bool operator==(const interval_view& rhs) const noexcept { return idx_ == rhs.idx_ && axis_ == rhs.axis_; } - bool operator!=(const interval_view &rhs) const noexcept { + bool operator!=(const interval_view& rhs) const noexcept { return !operator==(rhs); } @@ -44,7 +47,7 @@ template class interval_view { private: const int idx_; - const Axis &axis_; + const Axis& axis_; }; } // namespace axis diff --git a/include/boost/histogram/axis/iterator.hpp b/include/boost/histogram/axis/iterator.hpp index e1fa93328..b4ca35b3b 100644 --- a/include/boost/histogram/axis/iterator.hpp +++ b/include/boost/histogram/axis/iterator.hpp @@ -19,25 +19,26 @@ class iterator_over random_access_traversal_tag, typename Axis::bin_type> { public: - explicit iterator_over(const Axis &axis, int idx) : axis_(axis), idx_(idx) {} + explicit iterator_over(const Axis& axis, int idx) + : axis_(axis), idx_(idx) {} - iterator_over(const iterator_over &) = default; - iterator_over &operator=(const iterator_over &) = default; + iterator_over(const iterator_over&) = default; + iterator_over& operator=(const iterator_over&) = default; protected: void increment() noexcept { ++idx_; } void decrement() noexcept { --idx_; } void advance(int n) noexcept { idx_ += n; } - int distance_to(const iterator_over &other) const noexcept { + int distance_to(const iterator_over& other) const noexcept { return other.idx_ - idx_; } - bool equal(const iterator_over &other) const noexcept { + bool equal(const iterator_over& other) const noexcept { return &axis_ == &other.axis_ && idx_ == other.idx_; } typename Axis::bin_type dereference() const { return axis_[idx_]; } friend class ::boost::iterator_core_access; - const Axis &axis_; + const Axis& axis_; int idx_; }; @@ -47,26 +48,26 @@ class reverse_iterator_over reverse_iterator_over, typename Axis::bin_type, random_access_traversal_tag, typename Axis::bin_type> { public: - explicit reverse_iterator_over(const Axis &axis, int idx) + explicit reverse_iterator_over(const Axis& axis, int idx) : axis_(axis), idx_(idx) {} - reverse_iterator_over(const reverse_iterator_over &) = default; - reverse_iterator_over &operator=(const reverse_iterator_over &) = default; + reverse_iterator_over(const reverse_iterator_over&) = default; + reverse_iterator_over& operator=(const reverse_iterator_over&) = default; protected: void increment() noexcept { --idx_; } void decrement() noexcept { ++idx_; } void advance(int n) noexcept { idx_ -= n; } - int distance_to(const reverse_iterator_over &other) const noexcept { + int distance_to(const reverse_iterator_over& other) const noexcept { return other.idx_ - idx_; } - bool equal(const reverse_iterator_over &other) const noexcept { + bool equal(const reverse_iterator_over& other) const noexcept { return &axis_ == &other.axis_ && idx_ == other.idx_; } typename Axis::bin_type dereference() const { return axis_[idx_ - 1]; } friend class ::boost::iterator_core_access; - const Axis &axis_; + const Axis& axis_; int idx_; }; diff --git a/include/boost/histogram/axis/ostream_operators.hpp b/include/boost/histogram/axis/ostream_operators.hpp index 64ebfb614..2407b91ac 100644 --- a/include/boost/histogram/axis/ostream_operators.hpp +++ b/include/boost/histogram/axis/ostream_operators.hpp @@ -20,61 +20,56 @@ namespace histogram { namespace axis { namespace detail { -inline string_view to_string(const transform::identity &) { return {}; } -inline string_view to_string(const transform::log &) { return {"_log", 4}; } -inline string_view to_string(const transform::sqrt &) { return {"_sqrt", 5}; } +inline string_view to_string(const transform::identity&) { return {}; } +inline string_view to_string(const transform::log&) { return {"_log", 4}; } +inline string_view to_string(const transform::sqrt&) { return {"_sqrt", 5}; } } // namespace detail template -inline std::ostream &operator<<(std::ostream &os, const interval_view &i) { +inline std::ostream& operator<<(std::ostream& os, const interval_view& i) { os << "[" << i.lower() << ", " << i.upper() << ")"; return os; } template -inline std::ostream &operator<<(std::ostream &os, const value_view &i) { +inline std::ostream& operator<<(std::ostream& os, const value_view& i) { os << i.value(); return os; } template -inline std::ostream &operator<<(std::ostream &os, - const regular &a) { +inline std::ostream& operator<<(std::ostream& os, + const regular& a) { os << "regular" << detail::to_string(Transform()) << "(" << a.size() << ", " << a[0].lower() << ", " << a[a.size()].lower(); if (!a.label().empty()) { os << ", label="; ::boost::histogram::detail::escape(os, a.label()); } - if (!a.uoflow()) { - os << ", uoflow=False"; - } + if (!a.uoflow()) { os << ", uoflow=False"; } os << ")"; return os; } template -inline std::ostream & -operator<<(std::ostream &os, const regular &a) { +inline std::ostream& operator<<( + std::ostream& os, const regular& a) { os << "regular_pow(" << a.size() << ", " << a[0].lower() << ", " << a[a.size()].lower() << ", " << a.transform().power; if (!a.label().empty()) { os << ", label="; ::boost::histogram::detail::escape(os, a.label()); } - if (!a.uoflow()) { - os << ", uoflow=False"; - } + if (!a.uoflow()) { os << ", uoflow=False"; } os << ")"; return os; } template -inline std::ostream &operator<<(std::ostream &os, const circular &a) { +inline std::ostream& operator<<(std::ostream& os, + const circular& a) { os << "circular(" << a.size(); - if (a.phase() != 0.0) { - os << ", phase=" << a.phase(); - } + if (a.phase() != 0.0) { os << ", phase=" << a.phase(); } if (a.perimeter() != RealType(::boost::histogram::detail::two_pi)) { os << ", perimeter=" << a.perimeter(); } @@ -87,38 +82,33 @@ inline std::ostream &operator<<(std::ostream &os, const circular &a) { } template -inline std::ostream &operator<<(std::ostream &os, const variable &a) { +inline std::ostream& operator<<(std::ostream& os, + const variable& a) { os << "variable(" << a[0].lower(); - for (int i = 1; i <= a.size(); ++i) { - os << ", " << a[i].lower(); - } + for (int i = 1; i <= a.size(); ++i) { os << ", " << a[i].lower(); } if (!a.label().empty()) { os << ", label="; ::boost::histogram::detail::escape(os, a.label()); } - if (!a.uoflow()) { - os << ", uoflow=False"; - } + if (!a.uoflow()) { os << ", uoflow=False"; } os << ")"; return os; } template -inline std::ostream &operator<<(std::ostream &os, const integer &a) { +inline std::ostream& operator<<(std::ostream& os, const integer& a) { os << "integer(" << a[0].lower() << ", " << a[a.size()].lower(); if (!a.label().empty()) { os << ", label="; ::boost::histogram::detail::escape(os, a.label()); } - if (!a.uoflow()) { - os << ", uoflow=False"; - } + if (!a.uoflow()) { os << ", uoflow=False"; } os << ")"; return os; } template -inline std::ostream &operator<<(std::ostream &os, const category &a) { +inline std::ostream& operator<<(std::ostream& os, const category& a) { os << "category("; for (int i = 0; i < a.size(); ++i) { os << a[i] << (i == (a.size() - 1) ? "" : ", "); @@ -132,8 +122,8 @@ inline std::ostream &operator<<(std::ostream &os, const category &a) { } template <> -inline std::ostream &operator<<(std::ostream &os, - const category &a) { +inline std::ostream& operator<<(std::ostream& os, + const category& a) { os << "category("; for (int i = 0; i < a.size(); ++i) { ::boost::histogram::detail::escape(os, a.value(i)); diff --git a/include/boost/histogram/axis/types.hpp b/include/boost/histogram/axis/types.hpp index 6f852581c..98651ae9a 100644 --- a/include/boost/histogram/axis/types.hpp +++ b/include/boost/histogram/axis/types.hpp @@ -46,7 +46,8 @@ enum class uoflow { off = false, on = true }; #endif /// Base class for all axes, uses CRTP to inject iterator logic. -template class axis_base { +template +class axis_base { public: using const_iterator = iterator_over; using const_reverse_iterator = reverse_iterator_over; @@ -63,16 +64,16 @@ template class axis_base { void label(string_view label) { label_.assign(label.begin(), label.end()); } const_iterator begin() const noexcept { - return const_iterator(*static_cast(this), 0); + return const_iterator(*static_cast(this), 0); } const_iterator end() const noexcept { - return const_iterator(*static_cast(this), size()); + return const_iterator(*static_cast(this), size()); } const_reverse_iterator rbegin() const noexcept { - return const_reverse_iterator(*static_cast(this), size()); + return const_reverse_iterator(*static_cast(this), size()); } const_reverse_iterator rend() const noexcept { - return const_reverse_iterator(*static_cast(this), 0); + return const_reverse_iterator(*static_cast(this), 0); } protected: @@ -86,12 +87,13 @@ template class axis_base { } axis_base() = default; - axis_base(const axis_base &) = default; - axis_base &operator=(const axis_base &) = default; - axis_base(axis_base &&rhs) : size_(rhs.size_), label_(std::move(rhs.label_)) { + axis_base(const axis_base&) = default; + axis_base& operator=(const axis_base&) = default; + axis_base(axis_base&& rhs) + : size_(rhs.size_), label_(std::move(rhs.label_)) { rhs.size_ = 0; } - axis_base &operator=(axis_base &&rhs) { + axis_base& operator=(axis_base&& rhs) { if (this != &rhs) { size_ = rhs.size_; label_ = std::move(rhs.label_); @@ -100,7 +102,7 @@ template class axis_base { return *this; } - bool operator==(const axis_base &rhs) const noexcept { + bool operator==(const axis_base& rhs) const noexcept { return size_ == rhs.size_ && label_ == rhs.label_; } @@ -109,11 +111,13 @@ template class axis_base { std::string label_; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /// Base class for axes with optional under-/overflow bins, uses CRTP. -template class axis_base_uoflow : public axis_base { +template +class axis_base_uoflow : public axis_base { using base_type = axis_base; public: @@ -128,13 +132,13 @@ template class axis_base_uoflow : public axis_base { : base_type(n, label), shape_(n + 2 * static_cast(uo)) {} axis_base_uoflow() = default; - axis_base_uoflow(const axis_base_uoflow &) = default; - axis_base_uoflow &operator=(const axis_base_uoflow &) = default; - axis_base_uoflow(axis_base_uoflow &&rhs) + axis_base_uoflow(const axis_base_uoflow&) = default; + axis_base_uoflow& operator=(const axis_base_uoflow&) = default; + axis_base_uoflow(axis_base_uoflow&& rhs) : base_type(std::move(rhs)), shape_(rhs.shape_) { rhs.shape_ = 0; } - axis_base_uoflow &operator=(axis_base_uoflow &&rhs) { + axis_base_uoflow& operator=(axis_base_uoflow&& rhs) { if (this != &rhs) { base_type::operator=(std::move(rhs)); shape_ = rhs.shape_; @@ -143,7 +147,7 @@ template class axis_base_uoflow : public axis_base { return *this; } - bool operator==(const axis_base_uoflow &rhs) const noexcept { + bool operator==(const axis_base_uoflow& rhs) const noexcept { return base_type::operator==(rhs) && shape_ == rhs.shape_; } @@ -151,30 +155,50 @@ template class axis_base_uoflow : public axis_base { int shape_ = 0; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; namespace transform { namespace detail { struct stateless { - bool operator==(const stateless &) const noexcept { return true; } - template void serialize(Archive &, unsigned) {} + bool operator==(const stateless&) const noexcept { return true; } + template + void serialize(Archive&, unsigned) {} }; } // namespace detail struct identity : public detail::stateless { - template static T &&forward(T &&v) { return std::forward(v); } - template static T &&inverse(T &&v) { return std::forward(v); } + template + static T&& forward(T&& v) { + return std::forward(v); + } + template + static T&& inverse(T&& v) { + return std::forward(v); + } }; struct log : public detail::stateless { - template static T forward(T v) { return std::log(v); } - template static T inverse(T v) { return std::exp(v); } + template + static T forward(T v) { + return std::log(v); + } + template + static T inverse(T v) { + return std::exp(v); + } }; struct sqrt : public detail::stateless { - template static T forward(T v) { return std::sqrt(v); } - template static T inverse(T v) { return v * v; } + template + static T forward(T v) { + return std::sqrt(v); + } + template + static T inverse(T v) { + return v * v; + } }; // struct cos : public detail::stateless { @@ -187,17 +211,22 @@ struct pow { pow() = default; pow(double p) : power(p) {} - template T forward(T v) const { return std::pow(v, power); } - template T inverse(T v) const { + template + T forward(T v) const { + return std::pow(v, power); + } + template + T inverse(T v) const { return std::pow(v, 1.0 / power); } - bool operator==(const pow &other) const noexcept { + bool operator==(const pow& other) const noexcept { return power == other.power; } private: friend ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; } // namespace transform @@ -229,7 +258,9 @@ class regular : public axis_base_uoflow>, string_view label = {}, BOOST_HISTOGRAM_ENUM_CLASS_ARG uoflow uo = ::boost::histogram::axis::uoflow::on, Transform trans = Transform()) - : base_type(n, label, uo), Transform(trans), min_(trans.forward(lower)), + : base_type(n, label, uo), + Transform(trans), + min_(trans.forward(lower)), delta_((trans.forward(upper) - trans.forward(lower)) / n) { if (lower < upper) { BOOST_ASSERT(!std::isnan(min_)); @@ -240,10 +271,10 @@ class regular : public axis_base_uoflow>, } regular() = default; - regular(const regular &) = default; - regular &operator=(const regular &) = default; - regular(regular &&) = default; - regular &operator=(regular &&) = default; + regular(const regular&) = default; + regular& operator=(const regular&) = default; + regular(regular&&) = default; + regular& operator=(regular&&) = default; /// Returns the bin index for the passed argument. int index(value_type x) const noexcept { @@ -271,21 +302,22 @@ class regular : public axis_base_uoflow>, bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } - bool operator==(const regular &o) const noexcept { + bool operator==(const regular& o) const noexcept { return base_type::operator==(o) && Transform::operator==(o) && min_ == o.min_ && delta_ == o.delta_; } /// Access properties of the transform. - const Transform &transform() const noexcept { - return static_cast(*this); + const Transform& transform() const noexcept { + return static_cast(*this); } private: value_type min_ = 0.0, delta_ = 1.0; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /** Axis for real values on a circle. @@ -315,16 +347,16 @@ class circular : public axis_base> { : base_type(n, label), phase_(phase), perimeter_(perimeter) {} circular() = default; - circular(const circular &) = default; - circular &operator=(const circular &) = default; - circular(circular &&) = default; - circular &operator=(circular &&) = default; + circular(const circular&) = default; + circular& operator=(const circular&) = default; + circular(circular&&) = default; + circular& operator=(circular&&) = default; /// Returns the bin index for the passed argument. int index(value_type x) const noexcept { const value_type z = (x - phase_) / perimeter_; - const int i = - static_cast(std::floor(z * base_type::size())) % base_type::size(); + const int i = static_cast(std::floor(z * base_type::size())) % + base_type::size(); return i + (i < 0) * base_type::size(); } @@ -334,11 +366,9 @@ class circular : public axis_base> { return z * perimeter_ + phase_; } - bin_type operator[](int idx) const noexcept { - return bin_type(idx, *this); - } + bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } - bool operator==(const circular &o) const noexcept { + bool operator==(const circular& o) const noexcept { return base_type::operator==(o) && phase_ == o.phase_ && perimeter_ == o.perimeter_; } @@ -350,7 +380,8 @@ class circular : public axis_base> { value_type phase_ = 0.0, perimeter_ = 1.0; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /** Axis for non-equidistant bins on the real line. @@ -395,11 +426,11 @@ class variable : public axis_base_uoflow> { } variable() = default; - variable(const variable &o) + variable(const variable& o) : base_type(o), x_(new value_type[base_type::size() + 1]) { std::copy(o.x_.get(), o.x_.get() + base_type::size() + 1, x_.get()); } - variable &operator=(const variable &o) { + variable& operator=(const variable& o) { if (this != &o) { base_type::operator=(o); x_.reset(new value_type[base_type::size() + 1]); @@ -407,8 +438,8 @@ class variable : public axis_base_uoflow> { } return *this; } - variable(variable &&) = default; - variable &operator=(variable &&) = default; + variable(variable&&) = default; + variable& operator=(variable&&) = default; /// Returns the bin index for the passed argument. int index(value_type x) const noexcept { @@ -418,9 +449,7 @@ class variable : public axis_base_uoflow> { /// Returns the starting edge of the bin. value_type lower(int i) const noexcept { - if (i < 0) { - return -std::numeric_limits::infinity(); - } + if (i < 0) { return -std::numeric_limits::infinity(); } if (i > base_type::size()) { return std::numeric_limits::infinity(); } @@ -429,10 +458,8 @@ class variable : public axis_base_uoflow> { bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } - bool operator==(const variable &o) const noexcept { - if (!base_type::operator==(o)) { - return false; - } + bool operator==(const variable& o) const noexcept { + if (!base_type::operator==(o)) { return false; } return std::equal(x_.get(), x_.get() + base_type::size() + 1, o.x_.get()); } @@ -440,7 +467,8 @@ class variable : public axis_base_uoflow> { std::unique_ptr x_; // smaller size compared to std::vector friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /** Axis for an interval of integral values with unit steps. @@ -473,10 +501,10 @@ class integer : public axis_base_uoflow> { } integer() = default; - integer(const integer &) = default; - integer &operator=(const integer &) = default; - integer(integer &&) = default; - integer &operator=(integer &&) = default; + integer(const integer&) = default; + integer& operator=(const integer&) = default; + integer(integer&&) = default; + integer& operator=(integer&&) = default; /// Returns the bin index for the passed argument. int index(value_type x) const noexcept { @@ -486,9 +514,7 @@ class integer : public axis_base_uoflow> { /// Returns lower edge of the integral bin. value_type lower(int i) const noexcept { - if (i < 0) { - return -std::numeric_limits::max(); - } + if (i < 0) { return -std::numeric_limits::max(); } if (i > base_type::size()) { return std::numeric_limits::max(); } @@ -497,7 +523,7 @@ class integer : public axis_base_uoflow> { bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } - bool operator==(const integer &o) const noexcept { + bool operator==(const integer& o) const noexcept { return base_type::operator==(o) && min_ == o.min_; } @@ -505,7 +531,8 @@ class integer : public axis_base_uoflow> { value_type min_ = 0; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /** Axis which maps unique single values to bins (one on one). @@ -515,7 +542,8 @@ class integer : public axis_base_uoflow> { * for this axis, which counts values that are not part of the set. * Binning is a O(1) operation. The value type must be hashable. */ -template class category : public axis_base> { +template +class category : public axis_base> { using map_type = bimap; using base_type = axis_base>; @@ -524,17 +552,17 @@ template class category : public axis_base> { using bin_type = value_view; category() = default; - category(const category &rhs) + category(const category& rhs) : base_type(rhs), map_(new map_type(*rhs.map_)) {} - category &operator=(const category &rhs) { + category& operator=(const category& rhs) { if (this != &rhs) { base_type::operator=(rhs); map_.reset(new map_type(*rhs.map_)); } return *this; } - category(category &&rhs) = default; - category &operator=(category &&rhs) = default; + category(category&& rhs) = default; + category& operator=(category&& rhs) = default; /** Construct from an initializer list of strings. * @@ -543,33 +571,29 @@ template class category : public axis_base> { category(std::initializer_list seq, string_view label = {}) : base_type(seq.size(), label), map_(new map_type()) { int index = 0; - for (const auto &x : seq) - map_->insert({x, index++}); - if (index == 0) - throw std::invalid_argument("sequence is empty"); + for (const auto& x : seq) map_->insert({x, index++}); + if (index == 0) throw std::invalid_argument("sequence is empty"); } - template > + template < + typename Iterator, + typename = ::boost::histogram::detail::requires_iterator> category(Iterator begin, Iterator end, string_view label = {}) : base_type(std::distance(begin, end), label), map_(new map_type()) { int index = 0; - while (begin != end) - map_->insert({*begin++, index++}); - if (index == 0) - throw std::invalid_argument("iterator range is empty"); + while (begin != end) map_->insert({*begin++, index++}); + if (index == 0) throw std::invalid_argument("iterator range is empty"); } /// Returns the bin index for the passed argument. - int index(const value_type &x) const noexcept { + int index(const value_type& x) const noexcept { auto it = map_->left.find(x); - if (it == map_->left.end()) - return base_type::size(); + if (it == map_->left.end()) return base_type::size(); return it->second; } /// Returns the value for the bin index (performs a range check). - const value_type &value(int idx) const { + const value_type& value(int idx) const { auto it = map_->right.find(idx); if (it == map_->right.end()) throw std::out_of_range("category index out of range"); @@ -578,7 +602,7 @@ template class category : public axis_base> { bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } - bool operator==(const category &o) const noexcept { + bool operator==(const category& o) const noexcept { return base_type::operator==(o) && std::equal(map_->begin(), map_->end(), o.map_->begin()); } @@ -587,7 +611,8 @@ template class category : public axis_base> { std::unique_ptr map_; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; } // namespace axis } // namespace histogram diff --git a/include/boost/histogram/axis/value_view.hpp b/include/boost/histogram/axis/value_view.hpp index b0975c43b..5a259b01f 100644 --- a/include/boost/histogram/axis/value_view.hpp +++ b/include/boost/histogram/axis/value_view.hpp @@ -14,25 +14,26 @@ namespace boost { namespace histogram { namespace axis { -template class value_view { +template +class value_view { public: - value_view(int idx, const Axis &axis) : idx_(idx), axis_(axis) {} + value_view(int idx, const Axis& axis) : idx_(idx), axis_(axis) {} - value_view(const value_view &) = default; - value_view &operator=(const value_view &) = default; - value_view(value_view &&) = default; - value_view &operator=(value_view &&) = default; + value_view(const value_view&) = default; + value_view& operator=(const value_view&) = default; + value_view(value_view&&) = default; + value_view& operator=(value_view&&) = default; int idx() const noexcept { return idx_; } - auto value() const -> decltype(std::declval().value(0)) { + auto value() const -> decltype(std::declval().value(0)) { return axis_.value(idx_); } - bool operator==(const value_view &rhs) const noexcept { + bool operator==(const value_view& rhs) const noexcept { return idx_ == rhs.idx_ && axis_ == rhs.axis_; } - bool operator!=(const value_view &rhs) const noexcept { + bool operator!=(const value_view& rhs) const noexcept { return !operator==(rhs); } @@ -40,7 +41,7 @@ template class value_view { private: const int idx_; - const Axis &axis_; + const Axis& axis_; }; } // namespace axis diff --git a/include/boost/histogram/detail/axis_visitor.hpp b/include/boost/histogram/detail/axis_visitor.hpp index 0f91907a4..74bed2259 100644 --- a/include/boost/histogram/detail/axis_visitor.hpp +++ b/include/boost/histogram/detail/axis_visitor.hpp @@ -20,93 +20,102 @@ namespace detail { namespace { -template struct axes_equal_tuple_vecvar { - bool &equal; - const Tuple &t; - const VecVar &v; - axes_equal_tuple_vecvar(bool &eq, const Tuple &tt, const VecVar &vv) +template +struct axes_equal_tuple_vecvar { + bool& equal; + const Tuple& t; + const VecVar& v; + axes_equal_tuple_vecvar(bool& eq, const Tuple& tt, const VecVar& vv) : equal(eq), t(tt), v(vv) {} - template void operator()(Int) const { + template + void operator()(Int) const { using T = mp11::mp_at; auto tp = ::boost::get(&v[Int::value]); equal &= (tp && *tp == std::get(t)); } }; -template struct axes_assign_tuple_vecvar { - Tuple &t; - const VecVar &v; - axes_assign_tuple_vecvar(Tuple &tt, const VecVar &vv) : t(tt), v(vv) {} - template void operator()(Int) const { +template +struct axes_assign_tuple_vecvar { + Tuple& t; + const VecVar& v; + axes_assign_tuple_vecvar(Tuple& tt, const VecVar& vv) : t(tt), v(vv) {} + template + void operator()(Int) const { using T = mp11::mp_at; std::get(t) = ::boost::get(v[Int::value]); } }; -template struct axes_assign_vecvar_tuple { - VecVar &v; - const Tuple &t; - axes_assign_vecvar_tuple(VecVar &vv, const Tuple &tt) : v(vv), t(tt) {} - template void operator()(Int) const { +template +struct axes_assign_vecvar_tuple { + VecVar& v; + const Tuple& t; + axes_assign_vecvar_tuple(VecVar& vv, const Tuple& tt) : v(vv), t(tt) {} + template + void operator()(Int) const { v[Int::value] = std::get(t); } }; template -inline bool axes_equal_impl(mp11::mp_true, const std::tuple &t, - const std::tuple &u) { +inline bool axes_equal_impl(mp11::mp_true, const std::tuple& t, + const std::tuple& u) { return t == u; } template -inline bool axes_equal_impl(mp11::mp_false, const std::tuple &, - const std::tuple &) { +inline bool axes_equal_impl(mp11::mp_false, const std::tuple&, + const std::tuple&) { return false; } } // namespace template -inline bool axes_equal(const std::tuple &t, const std::tuple &u) { +inline bool axes_equal(const std::tuple& t, + const std::tuple& u) { return axes_equal_impl( mp11::mp_same, mp11::mp_list>(), t, u); } template -inline void axes_assign(std::tuple &t, const std::tuple &u) { - static_assert(std::is_same, mp11::mp_list>::value, - "cannot assign incompatible axes"); +inline void axes_assign(std::tuple& t, const std::tuple& u) { + static_assert( + std::is_same, mp11::mp_list>::value, + "cannot assign incompatible axes"); t = u; } template -inline bool axes_equal(const std::tuple &t, - const std::vector> &u) { - if (sizeof...(Ts) != u.size()) - return false; +inline bool axes_equal(const std::tuple& t, + const std::vector>& u) { + if (sizeof...(Ts) != u.size()) return false; bool equal = true; auto fn = - axes_equal_tuple_vecvar, std::vector>>( - equal, t, u); + axes_equal_tuple_vecvar, + std::vector>>(equal, t, u); mp11::mp_for_each>(fn); return equal; } template -inline void axes_assign(std::tuple &t, const std::vector> &u) { +inline void axes_assign(std::tuple& t, + const std::vector>& u) { auto fn = axes_assign_tuple_vecvar, std::vector>>(t, u); mp11::mp_for_each>(fn); } template -inline bool axes_equal(const std::vector> &t, - const std::tuple &u) { +inline bool axes_equal(const std::vector>& t, + const std::tuple& u) { return axes_equal(u, t); } template -inline void axes_assign(std::vector> &t, const std::tuple &u) { +inline void axes_assign(std::vector>& t, + const std::tuple& u) { t.resize(sizeof...(Us)); auto fn = axes_assign_vecvar_tuple>, std::tuple>(t, u); @@ -114,41 +123,45 @@ inline void axes_assign(std::vector> &t, const std::tuple -inline bool axes_equal(const std::vector> &t, - const std::vector> &u) { - if (t.size() != u.size()) - return false; +inline bool axes_equal(const std::vector>& t, + const std::vector>& u) { + if (t.size() != u.size()) return false; for (std::size_t i = 0; i < t.size(); ++i) { - if (t[i] != u[i]) - return false; + if (t[i] != u[i]) return false; } return true; } template -inline void axes_assign(std::vector> &t, - const std::vector> &u) { - for (std::size_t i = 0; i < t.size(); ++i) { - t[i] = u[i]; - } +inline void axes_assign(std::vector>& t, + const std::vector>& u) { + for (std::size_t i = 0; i < t.size(); ++i) { t[i] = u[i]; } } struct field_count_visitor : public static_visitor { std::size_t value = 1; - template void operator()(const T &t) { value *= t.shape(); } + template + void operator()(const T& t) { + value *= t.shape(); + } }; -template struct unary_visitor : public static_visitor { - Unary &unary; - unary_visitor(Unary &u) : unary(u) {} - template void operator()(const Axis &a) const { unary(a); } +template +struct unary_visitor : public static_visitor { + Unary& unary; + unary_visitor(Unary& u) : unary(u) {} + template + void operator()(const Axis& a) const { + unary(a); + } }; struct shape_vector_visitor { std::vector shapes; std::vector::iterator iter; shape_vector_visitor(unsigned n) : shapes(n) { iter = shapes.begin(); } - template void operator()(const Axis &a) { + template + void operator()(const Axis& a) { *iter++ = a.shape(); } }; diff --git a/include/boost/histogram/detail/cat.hpp b/include/boost/histogram/detail/cat.hpp index e29b74be5..55f9ed87f 100644 --- a/include/boost/histogram/detail/cat.hpp +++ b/include/boost/histogram/detail/cat.hpp @@ -17,16 +17,17 @@ namespace boost { namespace histogram { namespace detail { namespace { -__attribute__((unused)) void cat_impl(std::ostringstream &) {} +__attribute__((unused)) void cat_impl(std::ostringstream&) {} template -void cat_impl(std::ostringstream &os, const T &t, const Ts &... ts) { +void cat_impl(std::ostringstream& os, const T& t, const Ts&... ts) { os << t; cat_impl(os, ts...); } } // namespace -template std::string cat(const Ts &... args) { +template +std::string cat(const Ts&... args) { std::ostringstream os; cat_impl(os, args...); return os.str(); diff --git a/include/boost/histogram/detail/meta.hpp b/include/boost/histogram/detail/meta.hpp index 4683c4d81..dcba06265 100644 --- a/include/boost/histogram/detail/meta.hpp +++ b/include/boost/histogram/detail/meta.hpp @@ -20,29 +20,34 @@ namespace boost { namespace histogram { namespace detail { -#define BOOST_HISTOGRAM_MAKE_SFINAE(name, cond) \ - template struct name##_impl { \ - template struct SFINAE {}; \ - template static std::true_type Test(SFINAE *); \ - template static std::false_type Test(...); \ - using type = decltype(Test(nullptr)); \ - }; \ - template using name = typename name##_impl::type +#define BOOST_HISTOGRAM_MAKE_SFINAE(name, cond) \ + template \ + struct name##_impl { \ + template \ + struct SFINAE {}; \ + template \ + static std::true_type Test(SFINAE*); \ + template \ + static std::false_type Test(...); \ + using type = decltype(Test(nullptr)); \ + }; \ + template \ + using name = typename name##_impl::type BOOST_HISTOGRAM_MAKE_SFINAE(has_variance_support, - (std::declval().value(), - std::declval().variance())); + (std::declval().value(), + std::declval().variance())); -BOOST_HISTOGRAM_MAKE_SFINAE(has_method_lower, (std::declval().lower(0))); +BOOST_HISTOGRAM_MAKE_SFINAE(has_method_lower, (std::declval().lower(0))); BOOST_HISTOGRAM_MAKE_SFINAE(is_dynamic_container, - (std::begin(std::declval()))); + (std::begin(std::declval()))); BOOST_HISTOGRAM_MAKE_SFINAE(is_static_container, - (std::get<0>(std::declval()))); + (std::get<0>(std::declval()))); BOOST_HISTOGRAM_MAKE_SFINAE(is_castable_to_int, - (static_cast(std::declval()))); + (static_cast(std::declval()))); struct static_container_tag {}; struct dynamic_container_tag {}; @@ -55,30 +60,34 @@ using classify_container = typename std::conditional< dynamic_container_tag, no_container_tag>::type>::type; -template ().size(), - std::declval().increase(0), - std::declval()[0])> +template ().size(), + std::declval().increase(0), + std::declval()[0])> struct requires_storage {}; template (), ++std::declval())> + typename = decltype(*std::declval(), ++std::declval())> struct requires_iterator {}; template using requires_axis = - decltype(std::declval().size(), std::declval().shape(), - std::declval().uoflow(), std::declval().label(), - std::declval()[0]); + decltype(std::declval().size(), std::declval().shape(), + std::declval().uoflow(), std::declval().label(), + std::declval()[0]); namespace { struct bool_mask_impl { - std::vector &b; + std::vector& b; bool v; - template void operator()(Int) const { b[Int::value] = v; } + template + void operator()(Int) const { + b[Int::value] = v; + } }; } -template std::vector bool_mask(unsigned n, bool v) { +template +std::vector bool_mask(unsigned n, bool v) { std::vector b(n, !v); mp11::mp_for_each>(bool_mask_impl{b, v}); return b; @@ -88,7 +97,8 @@ template using rm_cv_ref = typename std::remove_cv::type>::type; -template using mp_size = mp11::mp_size>; +template +using mp_size = mp11::mp_size>; template using mp_at_c = mp11::mp_at_c, D>; @@ -98,8 +108,10 @@ using mp_union = mp11::mp_rename, mp11::mp_set_push_back>; namespace { -template struct selection_impl { - template using at = mp11::mp_at; +template +struct selection_impl { + template + using at = mp11::mp_at; using N = mp11::mp_list; using LNs = mp11::mp_assign; using type = mp11::mp_transform; @@ -113,17 +125,19 @@ template using unique_sorted = mp11::mp_unique>; namespace { -template struct sub_tuple_assign_impl { - const Src &src; - Dst &dst; - template void operator()(std::pair) const { +template +struct sub_tuple_assign_impl { + const Src& src; + Dst& dst; + template + void operator()(std::pair) const { std::get(dst) = std::get(src); } }; } template -selection make_sub_tuple(const T &t) { +selection make_sub_tuple(const T& t) { using U = selection; U u; using N1 = mp11::mp_list; diff --git a/include/boost/histogram/detail/utility.hpp b/include/boost/histogram/detail/utility.hpp index 2a0ad38b1..35f763a53 100644 --- a/include/boost/histogram/detail/utility.hpp +++ b/include/boost/histogram/detail/utility.hpp @@ -14,11 +14,11 @@ #include #include #include +#include #include #include #include #include -#include namespace boost { namespace histogram { @@ -27,7 +27,7 @@ namespace detail { // two_pi can be found in boost/math, but it is defined here to reduce deps constexpr double two_pi = 6.283185307179586; -inline void escape(std::ostream &os, const string_view s) { +inline void escape(std::ostream& os, const string_view s) { os << '\''; for (auto sit = s.begin(); sit != s.end(); ++sit) { if (*sit == '\'' && (sit == s.begin() || *(sit - 1) != '\\')) { @@ -41,7 +41,7 @@ inline void escape(std::ostream &os, const string_view s) { // the following is highly optimized code that runs in a hot loop; // please measure the performance impact of changes -inline void lin(std::size_t &out, std::size_t &stride, const int axis_size, +inline void lin(std::size_t& out, std::size_t& stride, const int axis_size, const int axis_shape, int j) noexcept { BOOST_ASSERT_MSG(stride == 0 || (-1 <= j && j <= axis_size), "index must be in bounds for this algorithm"); @@ -50,7 +50,8 @@ inline void lin(std::size_t &out, std::size_t &stride, const int axis_size, #ifndef _MSC_VER #pragma GCC diagnostic ignored "-Wstrict-overflow" #endif - stride *= (j < axis_shape) * axis_shape; // stride == 0 indicates out-of-range + stride *= + (j < axis_shape) * axis_shape; // stride == 0 indicates out-of-range } struct index_cache { @@ -61,8 +62,9 @@ struct index_cache { struct dim_visitor { mutable std::size_t stride; - mutable dim_t *dims; - template void operator()(const Axis &a) const noexcept { + mutable dim_t* dims; + template + void operator()(const Axis& a) const noexcept { *dims++ = dim_t{0, a.size(), stride}; stride *= a.shape(); } @@ -76,14 +78,11 @@ struct index_cache { index_cache(index_cache&&) = default; index_cache& operator=(index_cache&&) = default; - index_cache(const index_cache& o) : - dim_(o.dim_), dims_(new dim_t[o.dim_]) - { + index_cache(const index_cache& o) : dim_(o.dim_), dims_(new dim_t[o.dim_]) { std::copy(o.dims_.get(), o.dims_.get() + dim_, dims_.get()); } - index_cache& operator=(const index_cache& o) - { + index_cache& operator=(const index_cache& o) { if (this != &o) { if (o.dim_ != dim_) { dim_ = o.dim_; @@ -124,12 +123,12 @@ struct index_cache { struct index_mapper { std::size_t first = 0, second = 0; - index_mapper(const std::vector &nvec, - const std::vector &bvec) { + index_mapper(const std::vector& nvec, + const std::vector& bvec) { dims.reserve(nvec.size()); std::size_t s1 = 1, s2 = 1; auto bi = bvec.begin(); - for (const auto &ni : nvec) { + for (const auto& ni : nvec) { if (*bi) { dims.push_back({s1, s2}); s2 *= ni; @@ -139,8 +138,9 @@ struct index_mapper { s1 *= ni; ++bi; } - std::sort(dims.begin(), dims.end(), - [](const dim &a, const dim &b) { return a.stride1 > b.stride1; }); + std::sort(dims.begin(), dims.end(), [](const dim& a, const dim& b) { + return a.stride1 > b.stride1; + }); nfirst = s1; } @@ -148,7 +148,7 @@ struct index_mapper { ++first; second = 0; auto f = first; - for (const auto &d : dims) { + for (const auto& d : dims) { auto i = f / d.stride1; f -= i * d.stride1; second += i * d.stride2; @@ -166,13 +166,13 @@ struct index_mapper { template inline typename std::enable_if<(is_castable_to_int::value), int>::type -indirect_int_cast(T &&t) noexcept { +indirect_int_cast(T&& t) noexcept { return static_cast(std::forward(t)); } template inline typename std::enable_if::value), int>::type -indirect_int_cast(T &&) noexcept { +indirect_int_cast(T&&) noexcept { // Cannot use static_assert here, because this function is created as a // side-effect of TMP. It must be valid at compile-time. BOOST_ASSERT_MSG(false, "bin argument not convertible to int"); @@ -180,19 +180,19 @@ indirect_int_cast(T &&) noexcept { } template -inline void fill_storage(S &s, std::size_t idx, weight &&w) { +inline void fill_storage(S& s, std::size_t idx, weight&& w) { s.add(idx, w); } -template inline void fill_storage(S &s, std::size_t idx) { +template +inline void fill_storage(S& s, std::size_t idx) { s.increase(idx); } template -inline auto storage_get(const S &s, std::size_t idx, bool error) -> +inline auto storage_get(const S& s, std::size_t idx, bool error) -> typename S::const_reference { - if (error) - throw std::out_of_range("bin index out of range"); + if (error) throw std::out_of_range("bin index out of range"); return s[idx]; } diff --git a/include/boost/histogram/dynamic_histogram.hpp b/include/boost/histogram/dynamic_histogram.hpp index 7176d3735..6e299536c 100644 --- a/include/boost/histogram/dynamic_histogram.hpp +++ b/include/boost/histogram/dynamic_histogram.hpp @@ -62,22 +62,21 @@ class histogram { public: histogram() = default; - histogram(const histogram &) = default; - histogram(histogram &&) = default; - histogram &operator=(const histogram &) = default; - histogram &operator=(histogram &&) = default; + histogram(const histogram&) = default; + histogram(histogram&&) = default; + histogram& operator=(const histogram&) = default; + histogram& operator=(histogram&&) = default; template > - explicit histogram(Axis0 &&axis0, Axis &&... axis) + explicit histogram(Axis0&& axis0, Axis&&... axis) : axes_({any_axis_type(std::forward(axis0)), any_axis_type(std::forward(axis))...}) { storage_ = Storage(size_from_axes()); index_cache_.reset(*this); } - explicit histogram(axes_type&& axes) - : axes_(std::move(axes)) { + explicit histogram(axes_type&& axes) : axes_(std::move(axes)) { storage_ = Storage(size_from_axes()); index_cache_.reset(*this); } @@ -90,14 +89,14 @@ class histogram { } template - explicit histogram(const histogram &rhs) : storage_(rhs.storage_) { + explicit histogram(const histogram& rhs) : storage_(rhs.storage_) { detail::axes_assign(axes_, rhs.axes_); index_cache_.reset(*this); } template - histogram &operator=(const histogram &rhs) { - if (static_cast(this) != static_cast(&rhs)) { + histogram& operator=(const histogram& rhs) { + if (static_cast(this) != static_cast(&rhs)) { detail::axes_assign(axes_, rhs.axes_); storage_ = rhs.storage_; index_cache_.reset(*this); @@ -106,13 +105,14 @@ class histogram { } template - explicit histogram(dynamic_histogram &&rhs) + explicit histogram(dynamic_histogram&& rhs) : axes_(std::move(rhs.axes_)), storage_(std::move(rhs.storage_)) { index_cache_.reset(*this); } - template histogram &operator=(dynamic_histogram &&rhs) { - if (static_cast(this) != static_cast(&rhs)) { + template + histogram& operator=(dynamic_histogram&& rhs) { + if (static_cast(this) != static_cast(&rhs)) { axes_ = std::move(rhs.axes_); storage_ = std::move(rhs.storage_); index_cache_.reset(*this); @@ -121,46 +121,48 @@ class histogram { } template - bool operator==(const histogram &rhs) const noexcept { + bool operator==(const histogram& rhs) const noexcept { return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_; } template - bool operator!=(const histogram &rhs) const noexcept { + bool operator!=(const histogram& rhs) const noexcept { return !operator==(rhs); } template - histogram &operator+=(const histogram &rhs) { + histogram& operator+=(const histogram& rhs) { if (!detail::axes_equal(axes_, rhs.axes_)) throw std::invalid_argument("axes of histograms differ"); storage_ += rhs.storage_; return *this; } - template histogram &operator*=(const T &rhs) { + template + histogram& operator*=(const T& rhs) { storage_ *= rhs; return *this; } - template histogram &operator/=(const T &rhs) { + template + histogram& operator/=(const T& rhs) { storage_ *= 1.0 / rhs; return *this; } - template void operator()(Ts &&... ts) { + template + void operator()(Ts&&... ts) { // case with one argument is ambiguous, is specialized below BOOST_ASSERT_MSG(dim() == sizeof...(Ts), "fill arguments does not match histogram dimension " "(did you use weight() in the wrong place?)"); std::size_t idx = 0, stride = 1; xlin<0>(idx, stride, std::forward(ts)...); - if (stride) { - detail::fill_storage(storage_, idx); - } + if (stride) { detail::fill_storage(storage_, idx); } } - template void operator()(T &&t) { + template + void operator()(T&& t) { // check whether T is unpackable if (dim() == 1) { fill_impl(detail::no_container_tag(), std::forward(t)); @@ -170,19 +172,17 @@ class histogram { } template - void operator()(detail::weight &&w, Ts &&... ts) { + void operator()(detail::weight&& w, Ts&&... ts) { // case with one argument is ambiguous, is specialized below BOOST_ASSERT_MSG(dim() == sizeof...(Ts), "fill arguments does not match histogram dimension"); std::size_t idx = 0, stride = 1; xlin<0>(idx, stride, std::forward(ts)...); - if (stride) { - detail::fill_storage(storage_, idx, std::move(w)); - } + if (stride) { detail::fill_storage(storage_, idx, std::move(w)); } } template - void operator()(detail::weight &&w, T &&t) { + void operator()(detail::weight&& w, T&& t) { // check whether T is unpackable if (dim() == 1) { fill_impl(detail::no_container_tag(), std::forward(t), std::move(w)); @@ -192,7 +192,8 @@ class histogram { } } - template const_reference at(Ts &&... ts) const { + template + const_reference at(Ts&&... ts) const { // case with one argument is ambiguous, is specialized below BOOST_ASSERT_MSG(dim() == sizeof...(Ts), "bin arguments does not match histogram dimension"); @@ -201,12 +202,14 @@ class histogram { return detail::storage_get(storage_, idx, stride == 0); } - template const_reference at(T &&t) const { + template + const_reference at(T&& t) const { // check whether T is unpackable return at_impl(detail::classify_container(), std::forward(t)); } - template const_reference operator[](T &&t) const { + template + const_reference operator[](T&& t) const { // check whether T is unpackable return at_impl(detail::classify_container(), std::forward(t)); } @@ -221,20 +224,21 @@ class histogram { void reset() { storage_ = Storage(size_from_axes()); } /// Return axis \a i - any_axis_type &axis(unsigned i = 0) { + any_axis_type& axis(unsigned i = 0) { BOOST_ASSERT_MSG(i < dim(), "axis index out of range"); return axes_[i]; } /// Return axis \a i (const version) - const any_axis_type &axis(unsigned i = 0) const { + const any_axis_type& axis(unsigned i = 0) const { BOOST_ASSERT_MSG(i < dim(), "axis index out of range"); return axes_[i]; } /// Apply unary functor/function to each axis - template void for_each_axis(Unary &&unary) const { - for (const auto &a : axes_) { + template + void for_each_axis(Unary&& unary) const { + for (const auto& a : axes_) { apply_visitor(detail::unary_visitor(unary), a); } } @@ -247,10 +251,10 @@ class histogram { } /// Return a lower dimensional histogram - template histogram reduce_to(int n, Ts... ts) const { + template + histogram reduce_to(int n, Ts... ts) const { std::vector b(dim(), false); - for (const auto &i : {n, int(ts)...}) - b[i] = true; + for (const auto& i : {n, int(ts)...}) b[i] = true; return reduce_impl(b); } @@ -258,14 +262,11 @@ class histogram { template > histogram reduce_to(Iterator begin, Iterator end) const { std::vector b(dim(), false); - for (; begin != end; ++begin) - b[*begin] = true; + for (; begin != end; ++begin) b[*begin] = true; return reduce_impl(b); } - const_iterator begin() const noexcept { - return const_iterator(*this, 0); - } + const_iterator begin() const noexcept { return const_iterator(*this, 0); } const_iterator end() const noexcept { return const_iterator(*this, storage_.size()); @@ -283,7 +284,7 @@ class histogram { } template - void fill_impl(detail::dynamic_container_tag, T &&t, Ts &&... ts) { + void fill_impl(detail::dynamic_container_tag, T&& t, Ts&&... ts) { BOOST_ASSERT_MSG(dim() == std::distance(std::begin(t), std::end(t)), "fill container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -294,7 +295,7 @@ class histogram { } template - void fill_impl(detail::static_container_tag, T &&t, Ts &&... ts) { + void fill_impl(detail::static_container_tag, T&& t, Ts&&... ts) { BOOST_ASSERT_MSG(dim() == detail::mp_size::value, "fill container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -306,7 +307,7 @@ class histogram { } template - void fill_impl(detail::no_container_tag, T &&t, Ts &&... ts) { + void fill_impl(detail::no_container_tag, T&& t, Ts&&... ts) { BOOST_ASSERT_MSG(dim() == 1, "fill argument does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -317,7 +318,7 @@ class histogram { } template - const_reference at_impl(detail::dynamic_container_tag, T &&t) const { + const_reference at_impl(detail::dynamic_container_tag, T&& t) const { BOOST_ASSERT_MSG(dim() == std::distance(std::begin(t), std::end(t)), "bin container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -326,7 +327,7 @@ class histogram { } template - const_reference at_impl(detail::static_container_tag, T &&t) const { + const_reference at_impl(detail::static_container_tag, T&& t) const { BOOST_ASSERT_MSG(dim() == detail::mp_size::value, "bin container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -336,7 +337,7 @@ class histogram { } template - const_reference at_impl(detail::no_container_tag, T &&t) const { + const_reference at_impl(detail::no_container_tag, T&& t) const { BOOST_ASSERT_MSG(dim() == 1, "bin argument does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -345,49 +346,55 @@ class histogram { } struct lin_visitor : public static_visitor { - std::size_t &idx; - std::size_t &stride; + std::size_t& idx; + std::size_t& stride; const int j; - lin_visitor(std::size_t &i, std::size_t &s, const int x) noexcept + lin_visitor(std::size_t& i, std::size_t& s, const int x) noexcept : idx(i), stride(s), j(x) {} - template void operator()(const A &a) const noexcept { + template + void operator()(const A& a) const noexcept { const auto a_size = a.size(); const auto a_shape = a.shape(); - stride *= (-1 <= j && j <= a_size); // set stride to zero, if j is invalid + stride *= + (-1 <= j && j <= a_size); // set stride to zero, if j is invalid detail::lin(idx, stride, a_size, a_shape, j); } }; template - void lin(std::size_t &, std::size_t &) const noexcept {} + void lin(std::size_t&, std::size_t&) const noexcept {} template - void lin(std::size_t &idx, std::size_t &stride, int x, Ts... ts) const + void lin(std::size_t& idx, std::size_t& stride, int x, Ts... ts) const noexcept { apply_visitor(lin_visitor{idx, stride, x}, axes_[D]); lin(idx, stride, ts...); } - template struct xlin_visitor : public static_visitor { - std::size_t &idx; - std::size_t &stride; - const Value &val; - xlin_visitor(std::size_t &i, std::size_t &s, const Value &v) + template + struct xlin_visitor : public static_visitor { + std::size_t& idx; + std::size_t& stride; + const Value& val; + xlin_visitor(std::size_t& i, std::size_t& s, const Value& v) : idx(i), stride(s), val(v) {} - template void operator()(const Axis &a) const { + template + void operator()(const Axis& a) const { impl(std::is_convertible(), a); } - template void impl(std::true_type, const Axis &a) const { + template + void impl(std::true_type, const Axis& a) const { const auto a_size = a.size(); const auto a_shape = a.shape(); const auto j = a.index(val); detail::lin(idx, stride, a_size, a_shape, j); } - template void impl(std::false_type, const Axis &) const { + template + void impl(std::false_type, const Axis&) const { throw std::invalid_argument( detail::cat("fill argument not convertible to axis value type: ", boost::typeindex::type_id().pretty_name(), ", ", @@ -396,37 +403,36 @@ class histogram { }; template - void xlin(std::size_t &, std::size_t &) const {} + void xlin(std::size_t&, std::size_t&) const {} template - void xlin(std::size_t &idx, std::size_t &stride, T &&t, - Ts &&... ts) const { + void xlin(std::size_t& idx, std::size_t& stride, T&& t, Ts&&... ts) const { apply_visitor(xlin_visitor{idx, stride, t}, axes_[D]); xlin<(D + 1)>(idx, stride, std::forward(ts)...); } template - void lin_iter(std::size_t &idx, std::size_t &stride, - Iterator iter) const noexcept { - for (const auto &a : axes_) { + void lin_iter(std::size_t& idx, std::size_t& stride, Iterator iter) const + noexcept { + for (const auto& a : axes_) { apply_visitor(lin_visitor(idx, stride, *iter++), a); } } template - void xlin_iter(std::size_t &idx, std::size_t &stride, Iterator iter) const { - for (const auto &a : axes_) { + void xlin_iter(std::size_t& idx, std::size_t& stride, Iterator iter) const { + for (const auto& a : axes_) { apply_visitor(xlin_visitor{idx, stride, *iter++}, a); } } template - void xlin_get(mp11::mp_int<0>, std::size_t &, std::size_t &, T &&) const + void xlin_get(mp11::mp_int<0>, std::size_t&, std::size_t&, T&&) const noexcept {} template - void xlin_get(mp11::mp_int, std::size_t &idx, std::size_t &stride, - T &&t) const { + void xlin_get(mp11::mp_int, std::size_t& idx, std::size_t& stride, + T&& t) const { constexpr unsigned D = detail::mp_size::value - N; apply_visitor( xlin_visitor>{idx, stride, std::get(t)}, @@ -435,49 +441,49 @@ class histogram { } template - void lin_get(mp11::mp_int<0>, std::size_t &, std::size_t &, T &&) const + void lin_get(mp11::mp_int<0>, std::size_t&, std::size_t&, T&&) const noexcept {} template - void lin_get(mp11::mp_int, std::size_t &idx, std::size_t &stride, - T &&t) const noexcept { + void lin_get(mp11::mp_int, std::size_t& idx, std::size_t& stride, + T&& t) const noexcept { constexpr unsigned D = detail::mp_size::value - N; apply_visitor(lin_visitor{idx, stride, static_cast(std::get(t))}, axes_[D]); lin_get(mp11::mp_int<(N - 1)>(), idx, stride, std::forward(t)); } - histogram reduce_impl(const std::vector &b) const { + histogram reduce_impl(const std::vector& b) const { axes_type axes; std::vector n(b.size()); auto axes_iter = axes_.begin(); auto n_iter = n.begin(); - for (const auto &bi : b) { - if (bi) - axes.emplace_back(*axes_iter); + for (const auto& bi : b) { + if (bi) axes.emplace_back(*axes_iter); *n_iter = axes_iter->shape(); ++axes_iter; ++n_iter; } histogram h(std::move(axes)); detail::index_mapper m(n, b); - do { - h.storage_.add(m.second, storage_[m.first]); - } while (m.next()); + do { h.storage_.add(m.second, storage_[m.first]); } while (m.next()); return h; } - template friend class histogram; - template friend class iterator_over; + template + friend class histogram; + template + friend class iterator_over; friend class ::boost::python::access; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; template dynamic_histogram< mp11::mp_set_push_back...>> -make_dynamic_histogram(Axis &&... axis) { +make_dynamic_histogram(Axis&&... axis) { return dynamic_histogram< mp11::mp_set_push_back...>>( std::forward(axis)...); @@ -486,10 +492,10 @@ make_dynamic_histogram(Axis &&... axis) { template dynamic_histogram< mp11::mp_set_push_back...>, Storage> -make_dynamic_histogram_with(Axis &&... axis) { +make_dynamic_histogram_with(Axis&&... axis) { return dynamic_histogram< - mp11::mp_set_push_back...>, Storage>( - std::forward(axis)...); + mp11::mp_set_push_back...>, + Storage>(std::forward(axis)...); } template > diff --git a/include/boost/histogram/histogram_fwd.hpp b/include/boost/histogram/histogram_fwd.hpp index f7373f166..95001d7d9 100644 --- a/include/boost/histogram/histogram_fwd.hpp +++ b/include/boost/histogram/histogram_fwd.hpp @@ -15,7 +15,8 @@ namespace boost { namespace histogram { class adaptive_storage; -template class array_storage; +template +class array_storage; namespace axis { @@ -26,12 +27,17 @@ struct sqrt; struct pow; } // namespace transform -template +template class regular; -template class circular; -template class variable; -template class integer; -template class category; +template +class circular; +template +class variable; +template +class integer; +template +class category; using types = mp11::mp_list, axis::regular, @@ -41,7 +47,8 @@ using types = mp11::mp_list, axis::integer, axis::category, axis::category>; -template class any; +template +class any; using any_std = mp11::mp_rename; } // namespace axis @@ -58,18 +65,30 @@ template using static_histogram = histogram; namespace detail { -template struct weight { T value; }; +template +struct weight { + T value; +}; // template struct is_weight : std::false_type {}; // template struct is_weight> : std::true_type {}; -template struct sample { T value; }; +template +struct sample { + T value; +}; // template struct is_sample : std::false_type {}; // template struct is_sample> : std::true_type {}; } // namespace detail -template detail::weight weight(T &&t) { return {t}; } +template +detail::weight weight(T&& t) { + return {t}; +} -template detail::sample sample(T &&t) { return {t}; } +template +detail::sample sample(T&& t) { + return {t}; +} } // namespace histogram } // namespace boost diff --git a/include/boost/histogram/iterator.hpp b/include/boost/histogram/iterator.hpp index d24692982..1f0794f30 100644 --- a/include/boost/histogram/iterator.hpp +++ b/include/boost/histogram/iterator.hpp @@ -8,8 +8,8 @@ #define _BOOST_HISTOGRAM_VALUE_ITERATOR_HPP_ #include -#include #include +#include #include #include #include @@ -22,16 +22,14 @@ namespace histogram { template class iterator_over : public iterator_facade< - iterator_over, - typename Histogram::element_type, - random_access_traversal_tag, - typename Histogram::const_reference> { + iterator_over, typename Histogram::element_type, + random_access_traversal_tag, typename Histogram::const_reference> { public: - iterator_over(const Histogram &h, std::size_t idx) + iterator_over(const Histogram& h, std::size_t idx) : histogram_(h), idx_(idx) {} - iterator_over(const iterator_over &) = default; - iterator_over &operator=(const iterator_over &) = default; + iterator_over(const iterator_over&) = default; + iterator_over& operator=(const iterator_over&) = default; unsigned dim() const noexcept { return histogram_.dim(); } @@ -41,23 +39,23 @@ class iterator_over } auto bin() const - -> decltype(std::declval().axis(mp11::mp_int<0>())[0]) { + -> decltype(std::declval().axis(mp11::mp_int<0>())[0]) { return histogram_.axis(mp11::mp_int<0>())[idx(0)]; } template auto bin(mp11::mp_int) const - -> decltype(std::declval().axis(mp11::mp_int())[0]) { + -> decltype(std::declval().axis(mp11::mp_int())[0]) { return histogram_.axis(mp11::mp_int())[idx(Dim)]; } template // use SFINAE for this method - auto bin(unsigned dim) const -> decltype(std::declval().axis(dim)[0]) { + auto bin(unsigned dim) const -> decltype(std::declval().axis(dim)[0]) { return histogram_.axis(dim)[idx(dim)]; } private: - bool equal(const iterator_over &rhs) const noexcept { + bool equal(const iterator_over& rhs) const noexcept { return &histogram_ == &rhs.histogram_ && idx_ == rhs.idx_; } @@ -70,7 +68,7 @@ class iterator_over return histogram_.storage_[idx_]; } - const Histogram &histogram_; + const Histogram& histogram_; std::size_t idx_; friend class ::boost::iterator_core_access; }; diff --git a/include/boost/histogram/literals.hpp b/include/boost/histogram/literals.hpp index 3ab0793f5..a9cb2d8e5 100644 --- a/include/boost/histogram/literals.hpp +++ b/include/boost/histogram/literals.hpp @@ -13,21 +13,56 @@ namespace boost { namespace histogram { namespace literals { namespace detail { -template struct char2int; -template <> struct char2int<'0'> { static constexpr int value = 0; }; -template <> struct char2int<'1'> { static constexpr int value = 1; }; -template <> struct char2int<'2'> { static constexpr int value = 2; }; -template <> struct char2int<'3'> { static constexpr int value = 3; }; -template <> struct char2int<'4'> { static constexpr int value = 4; }; -template <> struct char2int<'5'> { static constexpr int value = 5; }; -template <> struct char2int<'6'> { static constexpr int value = 6; }; -template <> struct char2int<'7'> { static constexpr int value = 7; }; -template <> struct char2int<'8'> { static constexpr int value = 8; }; -template <> struct char2int<'9'> { static constexpr int value = 9; }; - -template constexpr int parse() { return N; } - -template constexpr int parse() { +template +struct char2int; +template <> +struct char2int<'0'> { + static constexpr int value = 0; +}; +template <> +struct char2int<'1'> { + static constexpr int value = 1; +}; +template <> +struct char2int<'2'> { + static constexpr int value = 2; +}; +template <> +struct char2int<'3'> { + static constexpr int value = 3; +}; +template <> +struct char2int<'4'> { + static constexpr int value = 4; +}; +template <> +struct char2int<'5'> { + static constexpr int value = 5; +}; +template <> +struct char2int<'6'> { + static constexpr int value = 6; +}; +template <> +struct char2int<'7'> { + static constexpr int value = 7; +}; +template <> +struct char2int<'8'> { + static constexpr int value = 8; +}; +template <> +struct char2int<'9'> { + static constexpr int value = 9; +}; + +template +constexpr int parse() { + return N; +} + +template +constexpr int parse() { return parse::value, Rest...>(); } } // namespace detail diff --git a/include/boost/histogram/ostream_operators.hpp b/include/boost/histogram/ostream_operators.hpp index 9c0b45650..0a2ef30db 100644 --- a/include/boost/histogram/ostream_operators.hpp +++ b/include/boost/histogram/ostream_operators.hpp @@ -16,16 +16,17 @@ namespace histogram { namespace detail { struct axis_ostream_visitor { - std::ostream &os_; - explicit axis_ostream_visitor(std::ostream &os) : os_(os) {} - template void operator()(const Axis &a) const { + std::ostream& os_; + explicit axis_ostream_visitor(std::ostream& os) : os_(os) {} + template + void operator()(const Axis& a) const { os_ << "\n " << a << ","; } }; } // namespace detail template -inline std::ostream &operator<<(std::ostream &os, const histogram &h) { +inline std::ostream& operator<<(std::ostream& os, const histogram& h) { os << "histogram("; h.for_each_axis(detail::axis_ostream_visitor(os)); os << (h.dim() ? "\n)" : ")"); @@ -33,7 +34,8 @@ inline std::ostream &operator<<(std::ostream &os, const histogram &h) { } template -inline std::ostream &operator<<(std::ostream &os, const weight_counter &x) { +inline std::ostream& operator<<(std::ostream& os, + const weight_counter& x) { os << "weight_counter(" << x.value() << ", " << x.variance() << ")"; return os; } diff --git a/include/boost/histogram/serialization.hpp b/include/boost/histogram/serialization.hpp index 4e0ba26c4..a9219f69c 100644 --- a/include/boost/histogram/serialization.hpp +++ b/include/boost/histogram/serialization.hpp @@ -28,89 +28,94 @@ namespace boost { namespace histogram { namespace detail { -template struct serialize_helper { - Archive &ar_; - explicit serialize_helper(Archive &ar) : ar_(ar) {} - template void operator()(T &t) const { ar_ &t; } +template +struct serialize_helper { + Archive& ar_; + explicit serialize_helper(Archive& ar) : ar_(ar) {} + template + void operator()(T& t) const { + ar_& t; + } }; } // namespace detail template template -void weight_counter::serialize(Archive &ar, unsigned /* version */) { - ar &w; - ar &w2; +void weight_counter::serialize(Archive& ar, + unsigned /* version */) { + ar& w; + ar& w2; } template -void serialize(Archive &ar, array_storage &store, +void serialize(Archive& ar, array_storage& store, unsigned /* version */) { - ar &store.array_; + ar& store.array_; } template -void adaptive_storage::serialize(Archive &ar, unsigned /* version */) { +void adaptive_storage::serialize(Archive& ar, unsigned /* version */) { auto size = this->size(); - ar &size; + ar& size; if (Archive::is_loading::value) { auto tid = 0u; - ar &tid; + ar& tid; if (tid == 0u) { buffer_ = detail::array(size); } else if (tid == 1u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } else if (tid == 2u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } else if (tid == 3u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } else if (tid == 4u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } else if (tid == 5u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } else if (tid == 6u) { detail::array a(size); - ar &serialization::make_array(a.begin(), size); + ar& serialization::make_array(a.begin(), size); buffer_ = std::move(a); } } else { auto tid = 0u; if (get>(&buffer_)) { tid = 0u; - ar &tid; - } else if (auto *a = get>(&buffer_)) { + ar& tid; + } else if (auto* a = get>(&buffer_)) { tid = 1u; - ar &tid; - ar &serialization::make_array(a->begin(), size); - } else if (auto *a = get>(&buffer_)) { + ar& tid; + ar& serialization::make_array(a->begin(), size); + } else if (auto* a = get>(&buffer_)) { tid = 2u; - ar &tid; - ar &serialization::make_array(a->begin(), size); - } else if (auto *a = get>(&buffer_)) { + ar& tid; + ar& serialization::make_array(a->begin(), size); + } else if (auto* a = get>(&buffer_)) { tid = 3u; - ar &tid; - ar &serialization::make_array(a->begin(), size); - } else if (auto *a = get>(&buffer_)) { + ar& tid; + ar& serialization::make_array(a->begin(), size); + } else if (auto* a = get>(&buffer_)) { tid = 4u; - ar &tid; - ar &serialization::make_array(a->begin(), size); - } else if (auto *a = get>(&buffer_)) { + ar& tid; + ar& serialization::make_array(a->begin(), size); + } else if (auto* a = get>(&buffer_)) { tid = 5u; - ar &tid; - ar &serialization::make_array(a->begin(), size); - } else if (auto *a = get>(&buffer_)) { + ar& tid; + ar& serialization::make_array(a->begin(), size); + } else if (auto* a = get>(&buffer_)) { tid = 6u; - ar &tid; - ar &serialization::make_array(a->begin(), size); + ar& tid; + ar& serialization::make_array(a->begin(), size); } } } @@ -119,90 +124,91 @@ namespace axis { template template -void axis_base::serialize(Archive &ar, unsigned /* version */) { - ar &size_; - ar &label_; +void axis_base::serialize(Archive& ar, unsigned /* version */) { + ar& size_; + ar& label_; } template template -void axis_base_uoflow::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object>(*this); - ar &shape_; +void axis_base_uoflow::serialize(Archive& ar, + unsigned /* version */) { + ar& boost::serialization::base_object>(*this); + ar& shape_; } namespace transform { template -void pow::serialize(Archive &ar, unsigned /* version */) { - ar &power; +void pow::serialize(Archive& ar, unsigned /* version */) { + ar& power; } } // namespace transform template template -void regular::serialize(Archive &ar, +void regular::serialize(Archive& ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); - ar &boost::serialization::base_object(*this); - ar &min_; - ar &delta_; + ar& boost::serialization::base_object(*this); + ar& boost::serialization::base_object(*this); + ar& min_; + ar& delta_; } template template -void circular::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); - ar &phase_; - ar &perimeter_; +void circular::serialize(Archive& ar, unsigned /* version */) { + ar& boost::serialization::base_object(*this); + ar& phase_; + ar& perimeter_; } template template -void variable::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); +void variable::serialize(Archive& ar, unsigned /* version */) { + ar& boost::serialization::base_object(*this); if (Archive::is_loading::value) { x_.reset(new RealType[base_type::size() + 1]); } - ar &boost::serialization::make_array(x_.get(), base_type::size() + 1); + ar& boost::serialization::make_array(x_.get(), base_type::size() + 1); } template template -void integer::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); - ar &min_; +void integer::serialize(Archive& ar, unsigned /* version */) { + ar& boost::serialization::base_object(*this); + ar& min_; } template template -void category::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); - ar &map_; +void category::serialize(Archive& ar, unsigned /* version */) { + ar& boost::serialization::base_object(*this); + ar& map_; } template template -void any::serialize(Archive &ar, unsigned /* version */) { - ar &boost::serialization::base_object(*this); +void any::serialize(Archive& ar, unsigned /* version */) { + ar& boost::serialization::base_object(*this); } } // namespace axis template template -void histogram::serialize(Archive &ar, +void histogram::serialize(Archive& ar, unsigned /* version */) { detail::serialize_helper sh(ar); mp11::tuple_for_each(axes_, sh); - ar &storage_; + ar& storage_; } template template -void histogram::serialize(Archive &ar, +void histogram::serialize(Archive& ar, unsigned /* version */) { - ar &axes_; - ar &storage_; + ar& axes_; + ar& storage_; } } // namespace histogram diff --git a/include/boost/histogram/static_histogram.hpp b/include/boost/histogram/static_histogram.hpp index 665a449c4..3adaca1ee 100644 --- a/include/boost/histogram/static_histogram.hpp +++ b/include/boost/histogram/static_histogram.hpp @@ -45,33 +45,33 @@ class histogram { using iterator = const_iterator; histogram() = default; - histogram(const histogram &rhs) = default; - histogram(histogram &&rhs) = default; - histogram &operator=(const histogram &rhs) = default; - histogram &operator=(histogram &&rhs) = default; + histogram(const histogram& rhs) = default; + histogram(histogram&& rhs) = default; + histogram& operator=(const histogram& rhs) = default; + histogram& operator=(histogram&& rhs) = default; template > - explicit histogram(Axis0 &&axis0, Axis &&... axis) + explicit histogram(Axis0&& axis0, Axis&&... axis) : axes_(std::forward(axis0), std::forward(axis)...) { storage_ = Storage(size_from_axes()); index_cache_.reset(*this); } - explicit histogram(axes_type &&axes) : axes_(std::move(axes)) { + explicit histogram(axes_type&& axes) : axes_(std::move(axes)) { storage_ = Storage(size_from_axes()); index_cache_.reset(*this); } template - explicit histogram(const static_histogram &rhs) + explicit histogram(const static_histogram& rhs) : axes_(rhs.axes_), storage_(rhs.storage_) { index_cache_.reset(*this); } template - histogram &operator=(const static_histogram &rhs) { - if (static_cast(this) != static_cast(&rhs)) { + histogram& operator=(const static_histogram& rhs) { + if (static_cast(this) != static_cast(&rhs)) { axes_ = rhs.axes_; storage_ = rhs.storage_; } @@ -79,15 +79,15 @@ class histogram { } template - explicit histogram(const dynamic_histogram &rhs) + explicit histogram(const dynamic_histogram& rhs) : storage_(rhs.storage_) { detail::axes_assign(axes_, rhs.axes_); index_cache_.reset(*this); } template - histogram &operator=(const dynamic_histogram &rhs) { - if (static_cast(this) != static_cast(&rhs)) { + histogram& operator=(const dynamic_histogram& rhs) { + if (static_cast(this) != static_cast(&rhs)) { detail::axes_assign(axes_, rhs.axes_); storage_ = rhs.storage_; index_cache_.reset(*this); @@ -96,27 +96,27 @@ class histogram { } template - bool operator==(const static_histogram &) const noexcept { + bool operator==(const static_histogram&) const noexcept { return false; } template - bool operator==(const static_histogram &rhs) const noexcept { + bool operator==(const static_histogram& rhs) const noexcept { return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_; } template - bool operator==(const dynamic_histogram &rhs) const noexcept { + bool operator==(const dynamic_histogram& rhs) const noexcept { return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_; } template - bool operator!=(const histogram &rhs) const noexcept { + bool operator!=(const histogram& rhs) const noexcept { return !operator==(rhs); } template - histogram &operator+=(const static_histogram &rhs) { + histogram& operator+=(const static_histogram& rhs) { if (!detail::axes_equal(axes_, rhs.axes_)) throw std::invalid_argument("axes of histograms differ"); storage_ += rhs.storage_; @@ -124,34 +124,37 @@ class histogram { } template - histogram &operator+=(const dynamic_histogram &rhs) { + histogram& operator+=(const dynamic_histogram& rhs) { if (!detail::axes_equal(axes_, rhs.axes_)) throw std::invalid_argument("axes of histograms differ"); storage_ += rhs.storage_; return *this; } - template histogram &operator*=(const T &rhs) { + template + histogram& operator*=(const T& rhs) { storage_ *= rhs; return *this; } - template histogram &operator/=(const T &rhs) { + template + histogram& operator/=(const T& rhs) { storage_ *= 1.0 / rhs; return *this; } - template void operator()(Ts &&... ts) { + template + void operator()(Ts&&... ts) { // case with one argument is ambiguous, is specialized below static_assert(sizeof...(Ts) == axes_size::value, "fill arguments do not match histogram dimension"); std::size_t idx = 0, stride = 1; xlin<0>(idx, stride, ts...); - if (stride) - detail::fill_storage(storage_, idx); + if (stride) detail::fill_storage(storage_, idx); } - template void operator()(T &&t) { + template + void operator()(T&& t) { // check whether we need to unpack argument fill_impl(mp11::mp_if_c<(axes_size::value == 1), detail::no_container_tag, detail::classify_container>(), @@ -160,24 +163,24 @@ class histogram { // TODO: merge this with unpacking template - void operator()(detail::weight &&w, Ts &&... ts) { + void operator()(detail::weight&& w, Ts&&... ts) { // case with one argument is ambiguous, is specialized below std::size_t idx = 0, stride = 1; xlin<0>(idx, stride, ts...); - if (stride) - detail::fill_storage(storage_, idx, std::move(w)); + if (stride) detail::fill_storage(storage_, idx, std::move(w)); } // TODO: remove as obsolete template - void operator()(detail::weight &&w, T &&t) { + void operator()(detail::weight&& w, T&& t) { // check whether we need to unpack argument fill_impl(mp11::mp_if_c<(axes_size::value == 1), detail::no_container_tag, detail::classify_container>(), std::forward(t), std::move(w)); } - template const_reference at(Ts &&... ts) const { + template + const_reference at(Ts&&... ts) const { // case with one argument is ambiguous, is specialized below static_assert(sizeof...(ts) == axes_size::value, "bin arguments do not match histogram dimension"); @@ -186,12 +189,14 @@ class histogram { return detail::storage_get(storage_, idx, stride == 0); } - template const_reference operator[](T &&t) const { + template + const_reference operator[](T&& t) const { // check whether we need to unpack argument return at_impl(detail::classify_container(), std::forward(t)); } - template const_reference at(T &&t) const { + template + const_reference at(T&& t) const { // check whether we need to unpack argument return at_impl(detail::classify_container(), std::forward(t)); } @@ -207,33 +212,34 @@ class histogram { /// Get N-th axis (const version) template - typename std::add_const::type>::type - &axis(mp11::mp_int) const { + typename std::add_const::type>:: + type& axis(mp11::mp_int) const { static_assert(N < axes_size::value, "axis index out of range"); return std::get(axes_); } /// Get N-th axis template - typename std::tuple_element::type &axis(mp11::mp_int) { + typename std::tuple_element::type& axis(mp11::mp_int) { static_assert(N < axes_size::value, "axis index out of range"); return std::get(axes_); } // Get first axis (convenience for 1-d histograms, const version) constexpr typename std::add_const< - typename std::tuple_element<0, axes_type>::type>::type & + typename std::tuple_element<0, axes_type>::type>::type& axis() const { return std::get<0>(axes_); } // Get first axis (convenience for 1-d histograms) - typename std::tuple_element<0, axes_type>::type &axis() { + typename std::tuple_element<0, axes_type>::type& axis() { return std::get<0>(axes_); } /// Apply unary functor/function to each axis - template void for_each_axis(Unary &&unary) const { + template + void for_each_axis(Unary&& unary) const { mp11::tuple_for_each(axes_, std::forward(unary)); } @@ -242,8 +248,9 @@ class histogram { auto reduce_to(mp11::mp_int, Ns...) const -> static_histogram, Ns...>, Storage> { - using HR = static_histogram, Ns...>, - Storage>; + using HR = + static_histogram, Ns...>, + Storage>; auto hr = HR(detail::make_sub_tuple, Ns...>(axes_)); const auto b = detail::bool_mask, Ns...>(dim(), true); @@ -251,9 +258,7 @@ class histogram { return hr; } - const_iterator begin() const noexcept { - return const_iterator(*this, 0); - } + const_iterator begin() const noexcept { return const_iterator(*this, 0); } const_iterator end() const noexcept { return const_iterator(*this, size()); @@ -271,10 +276,10 @@ class histogram { } template - void fill_impl(detail::dynamic_container_tag, T &&t, Ts &&... ts) { - BOOST_ASSERT_MSG(std::distance(std::begin(t), std::end(t)) == - axes_size::value, - "fill container does not match histogram dimension"); + void fill_impl(detail::dynamic_container_tag, T&& t, Ts&&... ts) { + BOOST_ASSERT_MSG( + std::distance(std::begin(t), std::end(t)) == axes_size::value, + "fill container does not match histogram dimension"); std::size_t idx = 0, stride = 1; xlin_iter(axes_size(), idx, stride, std::begin(t)); if (stride) { @@ -283,7 +288,7 @@ class histogram { } template - void fill_impl(detail::static_container_tag, T &&t, Ts &&... ts) { + void fill_impl(detail::static_container_tag, T&& t, Ts&&... ts) { static_assert(detail::mp_size::value == axes_size::value, "fill container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -294,7 +299,7 @@ class histogram { } template - void fill_impl(detail::no_container_tag, T &&t, Ts &&... ts) { + void fill_impl(detail::no_container_tag, T&& t, Ts&&... ts) { static_assert(axes_size::value == 1, "fill argument does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -305,17 +310,17 @@ class histogram { } template - const_reference at_impl(detail::dynamic_container_tag, T &&t) const { - BOOST_ASSERT_MSG(std::distance(std::begin(t), std::end(t)) == - axes_size::value, - "bin container does not match histogram dimension"); + const_reference at_impl(detail::dynamic_container_tag, T&& t) const { + BOOST_ASSERT_MSG( + std::distance(std::begin(t), std::end(t)) == axes_size::value, + "bin container does not match histogram dimension"); std::size_t idx = 0, stride = 1; lin_iter(axes_size(), idx, stride, std::begin(t)); return detail::storage_get(storage_, idx, stride == 0); } template - const_reference at_impl(detail::static_container_tag, T &&t) const { + const_reference at_impl(detail::static_container_tag, T&& t) const { static_assert(mp11::mp_size::value == axes_size::value, "bin container does not match histogram dimension"); std::size_t idx = 0, stride = 1; @@ -324,18 +329,17 @@ class histogram { } template - const_reference at_impl(detail::no_container_tag, T &&t) const { + const_reference at_impl(detail::no_container_tag, T&& t) const { std::size_t idx = 0, stride = 1; lin<0>(idx, stride, detail::indirect_int_cast(t)); return detail::storage_get(storage_, idx, stride == 0); } template - void xlin(std::size_t &, std::size_t &) const noexcept {} + void xlin(std::size_t&, std::size_t&) const noexcept {} template - void xlin(std::size_t &idx, std::size_t &stride, T &&t, - Ts &&... ts) const { + void xlin(std::size_t& idx, std::size_t& stride, T&& t, Ts&&... ts) const { const auto a_size = std::get(axes_).size(); const auto a_shape = std::get(axes_).shape(); const int j = std::get(axes_).index(t); @@ -344,11 +348,11 @@ class histogram { } template - void xlin_iter(mp11::mp_size_t<0>, std::size_t &, std::size_t &, + void xlin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&, Iterator) const noexcept {} template - void xlin_iter(mp11::mp_size_t, std::size_t &idx, std::size_t &stride, + void xlin_iter(mp11::mp_size_t, std::size_t& idx, std::size_t& stride, Iterator iter) const { constexpr unsigned D = axes_size::value - N; const auto a_size = std::get(axes_).size(); @@ -359,10 +363,10 @@ class histogram { } template - void lin(std::size_t &, std::size_t &) const noexcept {} + void lin(std::size_t&, std::size_t&) const noexcept {} template - void lin(std::size_t &idx, std::size_t &stride, int j, Ts... ts) const + void lin(std::size_t& idx, std::size_t& stride, int j, Ts... ts) const noexcept { const auto a_size = std::get(axes_).size(); const auto a_shape = std::get(axes_).shape(); @@ -372,11 +376,11 @@ class histogram { } template - void lin_iter(mp11::mp_size_t<0>, std::size_t &, std::size_t &, + void lin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&, Iterator) const noexcept {} template - void lin_iter(mp11::mp_size_t, std::size_t &idx, std::size_t &stride, + void lin_iter(mp11::mp_size_t, std::size_t& idx, std::size_t& stride, Iterator iter) const noexcept { constexpr unsigned D = axes_size::value - N; const auto a_size = std::get(axes_).size(); @@ -388,12 +392,12 @@ class histogram { } template - void xlin_get(mp11::mp_size_t<0>, std::size_t &, std::size_t &, T &&) const + void xlin_get(mp11::mp_size_t<0>, std::size_t&, std::size_t&, T&&) const noexcept {} template - void xlin_get(mp11::mp_size_t, std::size_t &idx, std::size_t &stride, - T &&t) const { + void xlin_get(mp11::mp_size_t, std::size_t& idx, std::size_t& stride, + T&& t) const { constexpr unsigned D = detail::mp_size::value - N; const auto a_size = std::get(axes_).size(); const auto a_shape = std::get(axes_).shape(); @@ -403,12 +407,12 @@ class histogram { } template - void lin_get(mp11::mp_size_t<0>, std::size_t &, std::size_t &, T &&) const + void lin_get(mp11::mp_size_t<0>, std::size_t&, std::size_t&, T&&) const noexcept {} template - void lin_get(mp11::mp_size_t, std::size_t &idx, std::size_t &stride, - T &&t) const noexcept { + void lin_get(mp11::mp_size_t, std::size_t& idx, std::size_t& stride, + T&& t) const noexcept { constexpr unsigned D = detail::mp_size::value - N; const auto a_size = std::get(axes_).size(); const auto a_shape = std::get(axes_).shape(); @@ -419,25 +423,26 @@ class histogram { } template - void reduce_impl(H &h, const std::vector &b) const { + void reduce_impl(H& h, const std::vector& b) const { detail::shape_vector_visitor v(dim()); for_each_axis(v); detail::index_mapper m(v.shapes, b); - do { - h.storage_.add(m.second, storage_[m.first]); - } while (m.next()); + do { h.storage_.add(m.second, storage_[m.first]); } while (m.next()); } - template friend class histogram; - template friend class iterator_over; + template + friend class histogram; + template + friend class iterator_over; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; /// default static type factory template static_histogram...>> -make_static_histogram(Axis &&... axis) { +make_static_histogram(Axis&&... axis) { return static_histogram...>>( std::forward(axis)...); } @@ -445,7 +450,7 @@ make_static_histogram(Axis &&... axis) { /// static type factory with variable storage type template static_histogram...>, Storage> -make_static_histogram_with(Axis &&... axis) { +make_static_histogram_with(Axis&&... axis) { return static_histogram...>, Storage>( std::forward(axis)...); } diff --git a/include/boost/histogram/storage/adaptive_storage.hpp b/include/boost/histogram/storage/adaptive_storage.hpp index 8239eb0c2..4103b2fad 100644 --- a/include/boost/histogram/storage/adaptive_storage.hpp +++ b/include/boost/histogram/storage/adaptive_storage.hpp @@ -43,9 +43,10 @@ namespace detail { using mp_int = ::boost::multiprecision::cpp_int; using wcount = ::boost::histogram::weight_counter; -template inline T *alloc(std::size_t s) { +template +inline T* alloc(std::size_t s) { #ifdef BOOST_HISTOGRAM_TRACE_ALLOCS - boost::core::typeinfo const &ti = BOOST_CORE_TYPEID(T); + boost::core::typeinfo const& ti = BOOST_CORE_TYPEID(T); std::cerr << "alloc " << boost::core::demangled_name(ti) << "[" << s << "]" << std::endl; #endif @@ -56,10 +57,10 @@ class array_base { public: explicit array_base(const std::size_t s) : size(s) {} array_base() = default; - array_base(const array_base &) = default; - array_base &operator=(const array_base &) = default; - array_base(array_base &&rhs) : size(rhs.size) { rhs.size = 0; } - array_base &operator=(array_base &&rhs) { + array_base(const array_base&) = default; + array_base& operator=(const array_base&) = default; + array_base(array_base&& rhs) : size(rhs.size) { rhs.size = 0; } + array_base& operator=(array_base&& rhs) { if (this != &rhs) { size = rhs.size; rhs.size = 0; @@ -69,16 +70,17 @@ class array_base { std::size_t size = 0; }; -template class array : public array_base { +template +class array : public array_base { public: explicit array(const std::size_t s) : array_base(s), ptr(alloc(s)) { std::fill(begin(), end(), T(0)); } array() = default; - array(const array &rhs) : array_base(rhs), ptr(alloc(rhs.size)) { + array(const array& rhs) : array_base(rhs), ptr(alloc(rhs.size)) { std::copy(rhs.begin(), rhs.end(), begin()); } - array &operator=(const array &rhs) { + array& operator=(const array& rhs) { if (this != &rhs) { if (size != rhs.size) { size = rhs.size; @@ -88,10 +90,10 @@ template class array : public array_base { } return *this; } - array(array &&rhs) : array_base(std::move(rhs)), ptr(std::move(rhs.ptr)) { + array(array&& rhs) : array_base(std::move(rhs)), ptr(std::move(rhs.ptr)) { rhs.size = 0; } - array &operator=(array &&rhs) { + array& operator=(array&& rhs) { if (this != &rhs) { size = rhs.size; ptr = std::move(rhs.ptr); @@ -102,25 +104,26 @@ template class array : public array_base { // copy only up to nmax elements template - array(const array &rhs, + array(const array& rhs, std::size_t nmax = std::numeric_limits::max()) : array_base(rhs), ptr(alloc(rhs.size)) { std::copy(rhs.begin(), rhs.begin() + std::min(nmax, size), begin()); } - T &operator[](const std::size_t i) { return ptr[i]; } - const T &operator[](const std::size_t i) const { return ptr[i]; } + T& operator[](const std::size_t i) { return ptr[i]; } + const T& operator[](const std::size_t i) const { return ptr[i]; } - T *begin() { return ptr.get(); } - T *end() { return ptr.get() + size; } - const T *begin() const { return ptr.get(); } - const T *end() const { return ptr.get() + size; } + T* begin() { return ptr.get(); } + T* end() { return ptr.get() + size; } + const T* begin() const { return ptr.get(); } + const T* end() const { return ptr.get() + size; } private: std::unique_ptr ptr; }; -template <> class array : public array_base { +template <> +class array : public array_base { public: using array_base::array_base; }; @@ -129,21 +132,36 @@ using any_array = variant, array, array, array, array, array, array>; -template struct next_type; -template <> struct next_type { using type = uint16_t; }; -template <> struct next_type { using type = uint32_t; }; -template <> struct next_type { using type = uint64_t; }; -template <> struct next_type { using type = mp_int; }; -template using next = typename next_type::type; +template +struct next_type; +template <> +struct next_type { + using type = uint16_t; +}; +template <> +struct next_type { + using type = uint32_t; +}; +template <> +struct next_type { + using type = uint64_t; +}; +template <> +struct next_type { + using type = mp_int; +}; +template +using next = typename next_type::type; -template inline bool safe_increase(T &t) { - if (t == std::numeric_limits::max()) - return false; +template +inline bool safe_increase(T& t) { + if (t == std::numeric_limits::max()) return false; ++t; return true; } -template inline bool safe_assign(T &t, const U &u) { +template +inline bool safe_assign(T& t, const U& u) { if (std::numeric_limits::max() < std::numeric_limits::max() && std::numeric_limits::max() < u) return false; @@ -151,57 +169,61 @@ template inline bool safe_assign(T &t, const U &u) { return true; } -template inline bool safe_radd(T &t, const U &u) { - if (static_cast(std::numeric_limits::max() - t) < u) - return false; +template +inline bool safe_radd(T& t, const U& u) { + if (static_cast(std::numeric_limits::max() - t) < u) return false; t += static_cast(u); return true; } // float rounding is a mess, the equal sign is necessary here -template inline bool safe_radd(T &t, const double u) { - if ((std::numeric_limits::max() - t) <= u) - return false; +template +inline bool safe_radd(T& t, const double u) { + if ((std::numeric_limits::max() - t) <= u) return false; t += u; return true; } struct size_visitor : public static_visitor { - template std::size_t operator()(const Array &b) const { + template + std::size_t operator()(const Array& b) const { return b.size; } }; -template struct assign_visitor : public static_visitor { - any_array &lhs_any; +template +struct assign_visitor : public static_visitor { + any_array& lhs_any; const std::size_t idx; - const RHS &rhs; - assign_visitor(any_array &a, const std::size_t i, const RHS &x) + const RHS& rhs; + assign_visitor(any_array& a, const std::size_t i, const RHS& x) : lhs_any(a), idx(i), rhs(x) {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { if (!safe_assign(lhs[idx], rhs)) { lhs_any = array>(lhs, idx); operator()(get>>(lhs_any)); } } - void operator()(array &lhs) const { + void operator()(array& lhs) const { lhs_any = array(lhs.size); operator()(get>(lhs_any)); } - void operator()(array &lhs) const { lhs[idx].assign(rhs); } + void operator()(array& lhs) const { lhs[idx].assign(rhs); } - void operator()(array &lhs) const { lhs[idx] = rhs; } + void operator()(array& lhs) const { lhs[idx] = rhs; } }; struct increase_visitor : public static_visitor { - any_array &lhs_any; + any_array& lhs_any; const std::size_t idx; - increase_visitor(any_array &a, const std::size_t i) : lhs_any(a), idx(i) {} + increase_visitor(any_array& a, const std::size_t i) : lhs_any(a), idx(i) {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { if (!safe_increase(lhs[idx])) { array> a = lhs; ++a[idx]; @@ -209,173 +231,182 @@ struct increase_visitor : public static_visitor { } } - void operator()(array &lhs) const { + void operator()(array& lhs) const { array a(lhs.size); ++a[idx]; lhs_any = std::move(a); } - void operator()(array &lhs) const { ++lhs[idx]; } + void operator()(array& lhs) const { ++lhs[idx]; } - void operator()(array &lhs) const { ++lhs[idx]; } + void operator()(array& lhs) const { ++lhs[idx]; } }; struct bin_visitor : public static_visitor { const std::size_t idx; bin_visitor(const std::size_t i) : idx(i) {} - template wcount operator()(const Array &b) const { + template + wcount operator()(const Array& b) const { return wcount(static_cast(b[idx])); } - wcount operator()(const array & /*b*/) const { return wcount(0.0); } + wcount operator()(const array& /*b*/) const { return wcount(0.0); } - wcount operator()(const array &b) const { return b[idx]; } + wcount operator()(const array& b) const { return b[idx]; } }; -template struct radd_visitor : public static_visitor { - any_array &lhs_any; +template +struct radd_visitor : public static_visitor { + any_array& lhs_any; const std::size_t idx; - const RHS &rhs; - radd_visitor(any_array &l, const std::size_t i, const RHS &r) + const RHS& rhs; + radd_visitor(any_array& l, const std::size_t i, const RHS& r) : lhs_any(l), idx(i), rhs(r) {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { if (!safe_radd(lhs[idx], rhs)) { lhs_any = array>(lhs); operator()(get>>(lhs_any)); } } - void operator()(array &lhs) const { + void operator()(array& lhs) const { if (rhs != 0) { lhs_any = array(lhs.size); operator()(get>(lhs_any)); } } - void operator()(array &lhs) const { + void operator()(array& lhs) const { lhs[idx] += static_cast(rhs); } - void operator()(array &lhs) const { lhs[idx] += rhs; } + void operator()(array& lhs) const { lhs[idx] += rhs; } }; -template <> struct radd_visitor : public static_visitor { - any_array &lhs_any; +template <> +struct radd_visitor : public static_visitor { + any_array& lhs_any; const std::size_t idx; - const mp_int &rhs; - radd_visitor(any_array &l, const std::size_t i, const mp_int &r) + const mp_int& rhs; + radd_visitor(any_array& l, const std::size_t i, const mp_int& r) : lhs_any(l), idx(i), rhs(r) {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { if (!safe_radd(lhs[idx], rhs)) { lhs_any = array>(lhs); operator()(get>>(lhs_any)); } } - void operator()(array &lhs) const { + void operator()(array& lhs) const { if (rhs != 0) { lhs_any = array(lhs.size); operator()(get>(lhs_any)); } } - void operator()(array &lhs) const { lhs[idx] += rhs; } + void operator()(array& lhs) const { lhs[idx] += rhs; } - void operator()(array &lhs) const { + void operator()(array& lhs) const { lhs[idx] += static_cast(rhs); } }; -template <> struct radd_visitor : public static_visitor { - any_array &lhs_any; +template <> +struct radd_visitor : public static_visitor { + any_array& lhs_any; const std::size_t idx; - const wcount &rhs; - radd_visitor(any_array &l, const std::size_t i, const wcount &r) + const wcount& rhs; + radd_visitor(any_array& l, const std::size_t i, const wcount& r) : lhs_any(l), idx(i), rhs(r) {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { lhs_any = array(lhs); operator()(get>(lhs_any)); } - void operator()(array &lhs) const { + void operator()(array& lhs) const { lhs_any = array(lhs.size); operator()(get>(lhs_any)); } - void operator()(array &lhs) const { lhs[idx] += rhs; } + void operator()(array& lhs) const { lhs[idx] += rhs; } }; -template <> struct radd_visitor> : public static_visitor { - any_array &lhs_any; +template <> +struct radd_visitor> : public static_visitor { + any_array& lhs_any; const std::size_t idx; const weight rhs; - radd_visitor(any_array &l, const std::size_t i, const double w) + radd_visitor(any_array& l, const std::size_t i, const double w) : lhs_any(l), idx(i), rhs{w} {} - template void operator()(array &lhs) const { + template + void operator()(array& lhs) const { lhs_any = array(lhs); operator()(get>(lhs_any)); } - void operator()(array &lhs) const { + void operator()(array& lhs) const { lhs_any = array(lhs.size); operator()(get>(lhs_any)); } - void operator()(array &lhs) const { lhs[idx] += rhs; } + void operator()(array& lhs) const { lhs[idx] += rhs; } }; // precondition: both arrays must have same size and may not be identical struct radd_array_visitor : public static_visitor { - any_array &lhs_any; - radd_array_visitor(any_array &l) : lhs_any(l) {} - template void operator()(const array &rhs) const { + any_array& lhs_any; + radd_array_visitor(any_array& l) : lhs_any(l) {} + template + void operator()(const array& rhs) const { for (std::size_t i = 0; i < rhs.size; ++i) apply_visitor(radd_visitor(lhs_any, i, rhs[i]), lhs_any); } - void operator()(const array &) const {} + void operator()(const array&) const {} }; struct rmul_visitor : public static_visitor { - any_array &lhs_any; + any_array& lhs_any; const double x; - rmul_visitor(any_array &l, const double v) : lhs_any(l), x(v) {} - template void operator()(array &lhs) const { + rmul_visitor(any_array& l, const double v) : lhs_any(l), x(v) {} + template + void operator()(array& lhs) const { lhs_any = array(lhs); operator()(get>(lhs_any)); } - void operator()(array &) const {} - void operator()(array &lhs) const { - for (std::size_t i = 0; i != lhs.size; ++i) - lhs[i] *= x; + void operator()(array&) const {} + void operator()(array& lhs) const { + for (std::size_t i = 0; i != lhs.size; ++i) lhs[i] *= x; } }; struct bicmp_visitor : public static_visitor { template - bool operator()(const array &b1, const array &b2) const { - if (b1.size != b2.size) - return false; + bool operator()(const array& b1, const array& b2) const { + if (b1.size != b2.size) return false; return std::equal(b1.begin(), b1.end(), b2.begin()); } template - bool operator()(const array &b1, const array &b2) const { - if (b1.size != b2.size) - return false; - return std::all_of(b1.begin(), b1.end(), [](const T &t) { return t == 0; }); + bool operator()(const array& b1, const array& b2) const { + if (b1.size != b2.size) return false; + return std::all_of(b1.begin(), b1.end(), + [](const T& t) { return t == 0; }); } template - bool operator()(const array &b1, const array &b2) const { + bool operator()(const array& b1, const array& b2) const { return operator()(b2, b1); } - bool operator()(const array &b1, const array &b2) const { + bool operator()(const array& b1, const array& b2) const { return b1.size == b2.size; } }; @@ -389,16 +420,17 @@ class adaptive_storage { using element_type = detail::wcount; using const_reference = element_type; - explicit adaptive_storage(std::size_t s) : buffer_(detail::array(s)) {} + explicit adaptive_storage(std::size_t s) + : buffer_(detail::array(s)) {} adaptive_storage() = default; - adaptive_storage(const adaptive_storage &) = default; - adaptive_storage &operator=(const adaptive_storage &) = default; - adaptive_storage(adaptive_storage &&) = default; - adaptive_storage &operator=(adaptive_storage &&) = default; + adaptive_storage(const adaptive_storage&) = default; + adaptive_storage& operator=(const adaptive_storage&) = default; + adaptive_storage(adaptive_storage&&) = default; + adaptive_storage& operator=(adaptive_storage&&) = default; template - explicit adaptive_storage(const RHS &rhs) + explicit adaptive_storage(const RHS& rhs) : buffer_(detail::array(rhs.size())) { using T = typename RHS::element_type; for (std::size_t i = 0, n = rhs.size(); i < n; ++i) { @@ -406,12 +438,11 @@ class adaptive_storage { } } - template adaptive_storage &operator=(const RHS &rhs) { + template + adaptive_storage& operator=(const RHS& rhs) { // no check for self-assign needed, default operator above is better match const auto n = rhs.size(); - if (size() != n) { - buffer_ = detail::array(n); - } + if (size() != n) { buffer_ = detail::array(n); } using T = typename RHS::element_type; for (std::size_t i = 0; i < n; ++i) { apply_visitor(detail::assign_visitor(buffer_, i, rhs[i]), buffer_); @@ -421,7 +452,7 @@ class adaptive_storage { // used in unit tests template - explicit adaptive_storage(const detail::array &a) : buffer_(a) {} + explicit adaptive_storage(const detail::array& a) : buffer_(a) {} std::size_t size() const { return apply_visitor(detail::size_visitor(), buffer_); @@ -431,20 +462,23 @@ class adaptive_storage { apply_visitor(detail::increase_visitor(buffer_, i), buffer_); } - void add(std::size_t i, const element_type &x) { + void add(std::size_t i, const element_type& x) { if (x.variance() == x.value()) { apply_visitor(detail::radd_visitor(buffer_, i, x.value()), buffer_); } else { - apply_visitor(detail::radd_visitor(buffer_, i, x), buffer_); + apply_visitor(detail::radd_visitor(buffer_, i, x), + buffer_); } } - template void add(std::size_t i, const T &t) { + template + void add(std::size_t i, const T& t) { apply_visitor(detail::radd_visitor(buffer_, i, t), buffer_); } - template void add(std::size_t i, const detail::weight &w) { + template + void add(std::size_t i, const detail::weight& w) { apply_visitor( detail::radd_visitor>(buffer_, i, w.value), buffer_); @@ -454,12 +488,12 @@ class adaptive_storage { return apply_visitor(detail::bin_visitor(i), buffer_); } - bool operator==(const adaptive_storage &rhs) const { + bool operator==(const adaptive_storage& rhs) const { return apply_visitor(detail::bicmp_visitor(), buffer_, rhs.buffer_); } // precondition: storages have same size - adaptive_storage &operator+=(const adaptive_storage &rhs) { + adaptive_storage& operator+=(const adaptive_storage& rhs) { if (this == &rhs) { for (std::size_t i = 0, n = size(); i < n; ++i) { add(i, rhs[i]); // may lose precision @@ -471,15 +505,17 @@ class adaptive_storage { } // precondition: storages have same size - template adaptive_storage &operator+=(const RHS &rhs) { + template + adaptive_storage& operator+=(const RHS& rhs) { for (std::size_t i = 0, n = size(); i < n; ++i) - apply_visitor( - detail::radd_visitor(buffer_, i, rhs[i]), - buffer_); + apply_visitor(detail::radd_visitor( + buffer_, i, rhs[i]), + buffer_); return *this; } - template adaptive_storage &operator*=(const T &x) { + template + adaptive_storage& operator*=(const T& x) { apply_visitor(detail::rmul_visitor(buffer_, x), buffer_); return *this; } @@ -489,7 +525,8 @@ class adaptive_storage { friend class ::boost::python::access; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; } // namespace histogram diff --git a/include/boost/histogram/storage/array_storage.hpp b/include/boost/histogram/storage/array_storage.hpp index 310b7f34d..ade9d079e 100644 --- a/include/boost/histogram/storage/array_storage.hpp +++ b/include/boost/histogram/storage/array_storage.hpp @@ -22,10 +22,11 @@ class access; namespace boost { namespace histogram { -template class array_storage { +template +class array_storage { public: using element_type = T; - using const_reference = const T &; + using const_reference = const T&; explicit array_storage(std::size_t s) : size_(s), array_(new element_type[s]) { @@ -33,22 +34,22 @@ template class array_storage { } array_storage() = default; - array_storage(const array_storage &other) + array_storage(const array_storage& other) : size_(other.size()), array_(new element_type[other.size()]) { std::copy(other.array_.get(), other.array_.get() + size_, array_.get()); } - array_storage &operator=(const array_storage &other) { + array_storage& operator=(const array_storage& other) { if (this != &other) { reset(other.size()); std::copy(other.array_.get(), other.array_.get() + size_, array_.get()); } return *this; } - array_storage(array_storage &&other) { + array_storage(array_storage&& other) { std::swap(size_, other.size_); std::swap(array_, other.array_); } - array_storage &operator=(array_storage &&other) { + array_storage& operator=(array_storage&& other) { if (this != &other) { std::swap(size_, other.size_); std::swap(array_, other.array_); @@ -57,14 +58,14 @@ template class array_storage { } template > - explicit array_storage(const S &other) { + explicit array_storage(const S& other) { reset(other.size()); for (std::size_t i = 0; i < size_; ++i) array_[i] = static_cast(other[i]); } template > - array_storage &operator=(const S &other) { + array_storage& operator=(const S& other) { reset(other.size()); for (std::size_t i = 0; i < size_; ++i) array_[i] = static_cast(other[i]); @@ -75,28 +76,30 @@ template class array_storage { void increase(std::size_t i) noexcept { ++array_[i]; } - template void add(std::size_t i, const U &x) noexcept { + template + void add(std::size_t i, const U& x) noexcept { array_[i] += x; } - const_reference operator[](std::size_t i) const noexcept { return array_[i]; } + const_reference operator[](std::size_t i) const noexcept { + return array_[i]; + } template - bool operator==(const array_storage &rhs) const noexcept { - if (size_ != rhs.size_) - return false; + bool operator==(const array_storage& rhs) const noexcept { + if (size_ != rhs.size_) return false; return std::equal(array_.get(), array_.get() + size_, rhs.array_.get()); } - template array_storage &operator+=(const S &rhs) noexcept { - for (std::size_t i = 0; i < size_; ++i) - add(i, rhs[i]); + template + array_storage& operator+=(const S& rhs) noexcept { + for (std::size_t i = 0; i < size_; ++i) add(i, rhs[i]); return *this; } - template array_storage &operator*=(const U &x) noexcept { - for (std::size_t i = 0; i < size_; ++i) - array_[i] *= x; + template + array_storage& operator*=(const U& x) noexcept { + for (std::size_t i = 0; i < size_; ++i) array_[i] *= x; return *this; } @@ -109,10 +112,12 @@ template class array_storage { array_.reset(new element_type[size]); } - template friend class array_storage; + template + friend class array_storage; friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned); + template + void serialize(Archive&, unsigned); }; } // namespace histogram diff --git a/include/boost/histogram/storage/operators.hpp b/include/boost/histogram/storage/operators.hpp index 271ffdfe6..bd4e696f5 100644 --- a/include/boost/histogram/storage/operators.hpp +++ b/include/boost/histogram/storage/operators.hpp @@ -14,18 +14,16 @@ namespace histogram { template , typename = detail::requires_storage> -bool operator==(const S1 &s1, const S2 &s2) noexcept { - if (s1.size() != s2.size()) - return false; +bool operator==(const S1& s1, const S2& s2) noexcept { + if (s1.size() != s2.size()) return false; for (std::size_t i = 0, n = s1.size(); i < n; ++i) - if (!(s1[i] == s2[i])) - return false; + if (!(s1[i] == s2[i])) return false; return true; } template , typename = detail::requires_storage> -bool operator!=(const S1 &s1, const S2 &s2) noexcept { +bool operator!=(const S1& s1, const S2& s2) noexcept { return !operator==(s1, s2); } diff --git a/include/boost/histogram/storage/weight_counter.hpp b/include/boost/histogram/storage/weight_counter.hpp index 534abc877..dca797913 100644 --- a/include/boost/histogram/storage/weight_counter.hpp +++ b/include/boost/histogram/storage/weight_counter.hpp @@ -19,145 +19,152 @@ class access; namespace histogram { /// Double counter which holds a sum of weights and a sum of squared weights -template class weight_counter { +template +class weight_counter { public: /// Beware: For performance reasons counters are not initialized weight_counter() = default; - weight_counter(const weight_counter &) = default; - weight_counter(weight_counter &&) = default; - weight_counter &operator=(const weight_counter &) = default; - weight_counter &operator=(weight_counter &&) = default; + weight_counter(const weight_counter&) = default; + weight_counter(weight_counter&&) = default; + weight_counter& operator=(const weight_counter&) = default; + weight_counter& operator=(weight_counter&&) = default; - weight_counter(const RealType &value, const RealType &variance) noexcept + weight_counter(const RealType& value, const RealType& variance) noexcept : w(value), w2(variance) {} - explicit weight_counter(const RealType &value) noexcept : w(value), + explicit weight_counter(const RealType& value) noexcept : w(value), w2(value) {} - weight_counter &operator++() { + weight_counter& operator++() { ++w; ++w2; return *this; } // TODO: explain why this is needed - weight_counter &operator+=(const RealType &x) { + weight_counter& operator+=(const RealType& x) { w += x; w2 += x; return *this; } template - weight_counter &operator+=(const weight_counter &rhs) { + weight_counter& operator+=(const weight_counter& rhs) { w += static_cast(rhs.w); w2 += static_cast(rhs.w2); return *this; } template - weight_counter &operator+=(const detail::weight &rhs) { + weight_counter& operator+=(const detail::weight& rhs) { const auto x = static_cast(rhs.value); w += x; w2 += x * x; return *this; } - weight_counter &operator*=(const RealType &x) { + weight_counter& operator*=(const RealType& x) { w *= x; w2 *= x * x; return *this; } - bool operator==(const weight_counter &rhs) const noexcept { + bool operator==(const weight_counter& rhs) const noexcept { return w == rhs.w && w2 == rhs.w2; } - bool operator!=(const weight_counter &rhs) const noexcept { + bool operator!=(const weight_counter& rhs) const noexcept { return !operator==(rhs); } template - bool operator==(const weight_counter &rhs) const noexcept { + bool operator==(const weight_counter& rhs) const noexcept { return w == rhs.w && w2 == rhs.w2; } template - bool operator!=(const weight_counter &rhs) const noexcept { + bool operator!=(const weight_counter& rhs) const noexcept { return !operator==(rhs); } - const RealType &value() const noexcept { return w; } - const RealType &variance() const noexcept { return w2; } + const RealType& value() const noexcept { return w; } + const RealType& variance() const noexcept { return w2; } // conversion - template explicit weight_counter(const T &t) { operator=(t); } - template weight_counter &operator=(const T &x) { + template + explicit weight_counter(const T& t) { + operator=(t); + } + template + weight_counter& operator=(const T& x) { w = w2 = static_cast(x); return *this; } // lossy conversion must be explicit - template explicit operator T() const { + template + explicit operator T() const { return static_cast(w); } private: friend class ::boost::serialization::access; - template void serialize(Archive &, unsigned /* version */); + template + void serialize(Archive&, unsigned /* version */); RealType w, w2; }; template -bool operator==(const weight_counter &w, const U &u) { +bool operator==(const weight_counter& w, const U& u) { return w.value() == w.variance() && w.value() == static_cast(u); } template -bool operator==(const T &t, const weight_counter &w) { +bool operator==(const T& t, const weight_counter& w) { return operator==(w, t); } template -bool operator!=(const weight_counter &w, const U &u) { +bool operator!=(const weight_counter& w, const U& u) { return !operator==(w, u); } template -bool operator!=(const T &t, const weight_counter &w) { +bool operator!=(const T& t, const weight_counter& w) { return operator!=(w, t); } template -weight_counter operator+(const weight_counter &a, - const weight_counter &b) noexcept { +weight_counter operator+(const weight_counter& a, + const weight_counter& b) noexcept { weight_counter c = a; return c += b; } template -weight_counter &&operator+(weight_counter &&a, - const weight_counter &b) noexcept { +weight_counter&& operator+(weight_counter&& a, + const weight_counter& b) noexcept { a += b; return std::move(a); } template -weight_counter &&operator+(const weight_counter &a, - weight_counter &&b) noexcept { +weight_counter&& operator+(const weight_counter& a, + weight_counter&& b) noexcept { return operator+(std::move(b), a); } template -weight_counter operator+(const weight_counter &a, const T &b) noexcept { +weight_counter operator+(const weight_counter& a, const T& b) noexcept { auto r = a; return r += b; } template -weight_counter operator+(const T &a, const weight_counter &b) noexcept { +weight_counter operator+(const T& a, const weight_counter& b) noexcept { auto r = b; return r += a; } diff --git a/src/python/axis.cpp b/src/python/axis.cpp index 1a426b05e..5d76aa30b 100644 --- a/src/python/axis.cpp +++ b/src/python/axis.cpp @@ -4,33 +4,34 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include "utility.hpp" -#include -#include #include #include +#include #include +#include #include #include -#include #include +#include #include +#include "utility.hpp" #ifdef HAVE_NUMPY #include namespace np = boost::python::numpy; #endif +#include #include +#include #include -#include #include -#include -#include +#include namespace bp = boost::python; namespace bh = boost::histogram; namespace bha = boost::histogram::axis; -template bp::str generic_repr(const T &t) { +template +bp::str generic_repr(const T& t) { std::ostringstream os; os << t; return os.str().c_str(); @@ -56,19 +57,15 @@ generic_iterator make_generic_iterator(bp::object self) { } template -struct axis_value_view_to_python -{ - static PyObject* convert(const bha::value_view &i) - { +struct axis_value_view_to_python { + static PyObject* convert(const bha::value_view& i) { return bp::incref(bp::object(i.value()).ptr()); } }; template -struct axis_interval_view_to_python -{ - static PyObject* convert(const bha::interval_view &i) - { +struct axis_interval_view_to_python { + static PyObject* convert(const bha::interval_view& i) { return bp::incref(bp::make_tuple(i.lower(), i.upper()).ptr()); } }; @@ -96,10 +93,8 @@ bp::object variable_init(bp::tuple args, bp::dict kwargs) { if (k == "label") label = boost::string_view(bp::extract(v), bp::len(v)); else if (k == "uoflow") { - if (!bp::extract(v)) - uo = bha::uoflow::off; - } - else { + if (!bp::extract(v)) uo = bha::uoflow::off; + } else { std::stringstream s; s << "keyword " << k << " not recognized"; PyErr_SetString(PyExc_KeyError, s.str().c_str()); @@ -142,46 +137,51 @@ bp::object category_init(bp::tuple args, bp::dict kwargs) { return self.attr("__init__")(bha::category<>(c.begin(), c.end(), label)); } -template void axis_set_label(T& t, bp::str s) { - t.label({bp::extract(s)(), - static_cast(bp::len(s))}); +template +void axis_set_label(T& t, bp::str s) { + t.label( + {bp::extract(s)(), static_cast(bp::len(s))}); } -template bp::str axis_get_label(const T& t) { +template +bp::str axis_get_label(const T& t) { auto s = t.label(); return {s.data(), s.size()}; } -template bp::object axis_getitem(const A &a, int i) { +template +bp::object axis_getitem(const A& a, int i) { if (i < -1 * a.uoflow() || i >= a.size() + 1 * a.uoflow()) throw std::out_of_range("index out of bounds"); - return bp::make_tuple(a.lower(i), a.lower(i+1)); + return bp::make_tuple(a.lower(i), a.lower(i + 1)); } -template <> bp::object axis_getitem>(const bha::category<> &a, int i) { - if (i < 0 || i >= a.size()) - throw std::out_of_range("index out of bounds"); +template <> +bp::object axis_getitem>(const bha::category<>& a, int i) { + if (i < 0 || i >= a.size()) throw std::out_of_range("index out of bounds"); return bp::object(a.value(i)); } #ifdef HAVE_NUMPY -template bp::object axis_array_interface(const Axis& axis) { +template +bp::object axis_array_interface(const Axis& axis) { using T = typename std::decay::type; bp::dict d; - auto shape = bp::make_tuple(axis.size()+1); + auto shape = bp::make_tuple(axis.size() + 1); d["shape"] = shape; d["typestr"] = bp::dtype_typestr(); // make new array, and pass it to Python auto a = np::empty(shape, np::dtype::get_builtin()); auto buf = reinterpret_cast(a.get_data()); - for (auto i = 0; i < axis.size()+1; ++i) - buf[i] = axis.lower(i); + for (auto i = 0; i < axis.size() + 1; ++i) buf[i] = axis.lower(i); d["data"] = a; d["version"] = 3; return d; } -template <> bp::object axis_array_interface>(const bha::category<>& axis) { +template <> +bp::object axis_array_interface>( + const bha::category<>& axis) { bp::dict d; auto shape = bp::make_tuple(axis.size()); d["shape"] = shape; @@ -189,8 +189,7 @@ template <> bp::object axis_array_interface>(const bha::category // make new array, and pass it to Python auto a = np::empty(shape, np::dtype::get_builtin()); auto buf = reinterpret_cast(a.get_data()); - for (auto i = 0; i < axis.size(); ++i) - buf[i] = axis.value(i); + for (auto i = 0; i < axis.size(); ++i) buf[i] = axis.value(i); d["data"] = a; d["version"] = 3; return d; @@ -199,15 +198,16 @@ template <> bp::object axis_array_interface>(const bha::category template struct axis_suite : public bp::def_visitor> { - template static void visit(Class &cl) { - cl.add_property( - "shape", &T::shape, - "Number of bins, including over-/underflow bins if they are present."); - cl.add_property( - "label", axis_get_label, axis_set_label, - "Name or description for the axis."); - cl.def("index", &T::index, ":param float x: value" - "\n:returns: bin index for the passed value", + template + static void visit(Class& cl) { + cl.add_property("shape", &T::shape, + "Number of bins, including over-/underflow bins if they " + "are present."); + cl.add_property("label", axis_get_label, axis_set_label, + "Name or description for the axis."); + cl.def("index", &T::index, + ":param float x: value" + "\n:returns: bin index for the passed value", bp::args("self", "x")); cl.def("__len__", &T::size, ":returns: number of bins, excluding over-/underflow bins.", @@ -227,39 +227,35 @@ struct axis_suite : public bp::def_visitor> { }; template -bha::regular* regular_init( - unsigned bin, double lower, double upper, - bp::str pylabel, bool with_uoflow) -{ +bha::regular* regular_init(unsigned bin, double lower, + double upper, bp::str pylabel, + bool with_uoflow) { const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off; - return new bha::regular(bin, lower, upper, - {bp::extract(pylabel)(), - static_cast(bp::len(pylabel))}, + return new bha::regular( + bin, lower, upper, {bp::extract(pylabel)(), + static_cast(bp::len(pylabel))}, uo); } bha::regular* regular_pow_init( - unsigned bin, double lower, double upper, double power, - bp::str pylabel, bool with_uoflow) -{ + unsigned bin, double lower, double upper, double power, bp::str pylabel, + bool with_uoflow) { using namespace ::boost::python; const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off; return new bha::regular( - bin, lower, upper, - {extract(pylabel)(), - static_cast(bp::len(pylabel))}, + bin, lower, upper, {extract(pylabel)(), + static_cast(bp::len(pylabel))}, uo, power); } -bha::integer<>* integer_init(int lower, int upper, - bp::str pylabel, bool with_uoflow) -{ +bha::integer<>* integer_init(int lower, int upper, bp::str pylabel, + bool with_uoflow) { using namespace ::boost::python; const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off; return new bha::integer<>(lower, upper, - {extract(pylabel)(), - static_cast(bp::len(pylabel))}, - uo); + {extract(pylabel)(), + static_cast(bp::len(pylabel))}, + uo); } void register_axis_types() { @@ -268,32 +264,34 @@ void register_axis_types() { docstring_options dopt(true, true, false); class_("generic_iterator", init()) - .def("__iter__", &generic_iterator::self, return_internal_reference<>()) - .def("__next__", &generic_iterator::next) // Python3 - .def("next", &generic_iterator::next) // Python2 - ; - - class_>( - "regular", - "Axis for real-valued data and bins of equal width." - "\nBinning is a O(1) operation.", - no_init) - .def("__init__", make_constructor(regular_init, - default_call_policies(), - (arg("bin"), arg("lower"), arg("upper"), - arg("label") = "", arg("uoflow") = true))) + .def("__iter__", &generic_iterator::self, return_internal_reference<>()) + .def("__next__", &generic_iterator::next) // Python3 + .def("next", &generic_iterator::next) // Python2 + ; + + class_>("regular", + "Axis for real-valued data and bins of equal width." + "\nBinning is a O(1) operation.", + no_init) + .def("__init__", + make_constructor(regular_init, + default_call_policies(), + (arg("bin"), arg("lower"), arg("upper"), + arg("label") = "", arg("uoflow") = true))) .def(axis_suite>()); -#define BOOST_HISTOGRAM_PYTHON_REGULAR_CLASS(x) \ - class_>( \ - "regular_"#x, \ - "Axis for real-valued data and bins of equal width in "#x"-space." \ - "\nBinning is a O(1) operation.", \ - no_init) \ - .def("__init__", make_constructor(regular_init, \ - default_call_policies(), \ - (arg("bin"), arg("lower"), arg("upper"), \ - arg("label") = "", arg("uoflow") = true))) \ +#define BOOST_HISTOGRAM_PYTHON_REGULAR_CLASS(x) \ + class_>( \ + "regular_" #x, \ + "Axis for real-valued data and bins of equal width in " #x \ + "-space." \ + "\nBinning is a O(1) operation.", \ + no_init) \ + .def("__init__", \ + make_constructor(regular_init, \ + default_call_policies(), \ + (arg("bin"), arg("lower"), arg("upper"), \ + arg("label") = "", arg("uoflow") = true))) \ .def(axis_suite>()) BOOST_HISTOGRAM_PYTHON_REGULAR_CLASS(log); @@ -305,10 +303,11 @@ void register_axis_types() { "Axis for real-valued data and bins of equal width in power-space." "\nBinning is a O(1) operation.", no_init) - .def("__init__", make_constructor(regular_pow_init, - default_call_policies(), - (arg("bin"), arg("lower"), arg("upper"), arg("power"), - arg("label") = "", arg("uoflow") = true))) + .def("__init__", + make_constructor( + regular_pow_init, default_call_policies(), + (arg("bin"), arg("lower"), arg("upper"), arg("power"), + arg("label") = "", arg("uoflow") = true))) .def(axis_suite>()); class_>( @@ -320,8 +319,7 @@ void register_axis_types() { no_init) .def(init( (arg("self"), arg("bin"), arg("phase") = 0.0, - arg("perimeter") = bh::detail::two_pi, - arg("label") = ""))) + arg("perimeter") = bh::detail::two_pi, arg("label") = ""))) .def(axis_suite>()); class_>( @@ -331,7 +329,7 @@ void register_axis_types() { "\nthe problem domain allows it, prefer a regular axis.", no_init) .def("__init__", raw_function(variable_init)) - .def(init &>()) + .def(init&>()) .def(axis_suite>()); class_>( @@ -340,10 +338,10 @@ void register_axis_types() { "\nthat are one integer wide. Faster than a regular axis." "\nBinning is a O(1) operation.", no_init) - .def("__init__", make_constructor(integer_init, - default_call_policies(), - (arg("lower"), arg("upper"), arg("label") = "", - arg("uoflow") = true))) + .def("__init__", + make_constructor(integer_init, default_call_policies(), + (arg("lower"), arg("upper"), arg("label") = "", + arg("uoflow") = true))) .def(axis_suite>()); class_>( @@ -354,6 +352,6 @@ void register_axis_types() { "\nBinning is a O(1) operation.", no_init) .def("__init__", raw_function(category_init)) - .def(init &>()) + .def(init&>()) .def(axis_suite>()); } diff --git a/src/python/histogram.cpp b/src/python/histogram.cpp index 6319ac503..e3549e9c2 100644 --- a/src/python/histogram.cpp +++ b/src/python/histogram.cpp @@ -4,18 +4,18 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include "serialization_suite.hpp" -#include "utility.hpp" +#include #include -#include #include #include -#include +#include #include #include #include #include #include +#include "serialization_suite.hpp" +#include "utility.hpp" #ifdef HAVE_NUMPY #include namespace np = boost::python::numpy; @@ -44,8 +44,8 @@ class access { using array = bh::detail::array; struct dtype_visitor : public boost::static_visitor { - list & shapes, & strides; - dtype_visitor(list &sh, list &st) : shapes(sh), strides(st) {} + list &shapes, &strides; + dtype_visitor(list& sh, list& st) : shapes(sh), strides(st) {} template str operator()(const array& /*unused*/) const { strides.append(sizeof(T)); @@ -85,26 +85,25 @@ class access { // double array, fill it and pass it auto a = np::empty(tuple(shapes), np::dtype::get_builtin()); for (auto i = 0l, n = bp::len(shapes); i < n; ++i) - const_cast(a.get_strides())[i] = bp::extract(strides[i]); - auto *buf = (double *)a.get_data(); - for (auto i = 0ul; i < b.size; ++i) - buf[i] = static_cast(b[i]); + const_cast(a.get_strides())[i] = + bp::extract(strides[i]); + auto* buf = (double*)a.get_data(); + for (auto i = 0ul; i < b.size; ++i) buf[i] = static_cast(b[i]); return a; } }; - static object array_interface(const pyhistogram &self) { + static object array_interface(const pyhistogram& self) { dict d; list shapes; list strides; - auto &b = self.storage_.buffer_; + auto& b = self.storage_.buffer_; d["typestr"] = boost::apply_visitor(dtype_visitor(shapes, strides), b); for (auto i = 0u; i < self.dim(); ++i) { if (i) strides.append(strides[-1] * shapes[-1]); shapes.append(self.axis(i).shape()); } - if (self.dim() == 0) - shapes.append(0); + if (self.dim() == 0) shapes.append(0); d["shape"] = tuple(shapes); d["strides"] = tuple(strides); d["data"] = boost::apply_visitor(data_visitor(shapes, strides), b); @@ -117,7 +116,8 @@ class access { } // namespace boost struct axis_visitor : public boost::static_visitor { - template bp::object operator()(const T &t) const { + template + bp::object operator()(const T& t) const { return bp::object(t); } }; @@ -126,9 +126,10 @@ struct axes_appender { bp::object obj; pyhistogram::axes_type& axes; bool& success; - axes_appender(bp::object o, pyhistogram::axes_type& a, - bool& s) : obj(o), axes(a), success(s) {} - template void operator()(const A&) const { + axes_appender(bp::object o, pyhistogram::axes_type& a, bool& s) + : obj(o), axes(a), success(s) {} + template + void operator()(const A&) const { if (success) return; bp::extract get_axis(obj); if (get_axis.check()) { @@ -138,9 +139,8 @@ struct axes_appender { } }; -bp::object histogram_axis(const pyhistogram &self, int i) { - if (i < 0) - i += self.dim(); +bp::object histogram_axis(const pyhistogram& self, int i) { + if (i < 0) i += self.dim(); if (i < 0 || i >= int(self.dim())) throw std::out_of_range("axis index out of range"); return boost::apply_visitor(axis_visitor(), self.axis(i)); @@ -163,8 +163,7 @@ bp::object histogram_init(bp::tuple args, bp::dict kwargs) { bp::object pa = args[i + 1]; bool success = false; boost::mp11::mp_for_each( - axes_appender(pa, axes, success) - ); + axes_appender(pa, axes, success)); if (!success) { std::string msg = "require an axis object, got "; msg += bp::extract(pa.attr("__class__"))(); @@ -204,8 +203,7 @@ struct fetcher { } const T& operator[](long i) const noexcept { - if (n > 0) - return carray[i]; + if (n > 0) return carray[i]; return value; } }; @@ -220,18 +218,20 @@ struct span { bp::object histogram_fill(bp::tuple args, bp::dict kwargs) { const auto nargs = bp::len(args); - pyhistogram &self = bp::extract(args[0]); + pyhistogram& self = bp::extract(args[0]); const unsigned dim = nargs - 1; if (dim != self.dim()) { - PyErr_SetString(PyExc_ValueError, "number of arguments and dimension do not match"); + PyErr_SetString(PyExc_ValueError, + "number of arguments and dimension do not match"); bp::throw_error_already_set(); } if (dim > BOOST_HISTOGRAM_AXIS_LIMIT) { PyErr_SetString(PyExc_RuntimeError, - bh::detail::cat("too many arguments, maximum is ", - BOOST_HISTOGRAM_AXIS_LIMIT).c_str()); + bh::detail::cat("too many arguments, maximum is ", + BOOST_HISTOGRAM_AXIS_LIMIT) + .c_str()); bp::throw_error_already_set(); } @@ -241,7 +241,8 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) { fetch[d].assign(args[1 + d]); if (fetch[d].n > 0) { if (n > 0 && fetch[d].n != n) { - PyErr_SetString(PyExc_ValueError, "lengths of sequences do not match"); + PyErr_SetString(PyExc_ValueError, + "lengths of sequences do not match"); bp::throw_error_already_set(); } n = fetch[d].n; @@ -261,7 +262,8 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) { fetch_weight.assign(kwargs.get("weight")); if (fetch_weight.n > 0) { if (n > 0 && fetch_weight.n != n) { - PyErr_SetString(PyExc_ValueError, "length of weight sequence does not match"); + PyErr_SetString(PyExc_ValueError, + "length of weight sequence does not match"); bp::throw_error_already_set(); } n = fetch_weight.n; @@ -275,22 +277,18 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) { for (auto i = 0l; i < n; ++i) self(bh::weight(fetch_weight[i]), fetch[0][i]); } else { - for (auto i = 0l; i < n; ++i) - self(fetch[0][i]); + for (auto i = 0l; i < n; ++i) self(fetch[0][i]); } } else { double v[BOOST_HISTOGRAM_AXIS_LIMIT]; if (fetch_weight.n >= 0) { for (auto i = 0l; i < n; ++i) { - for (auto d = 0u; d < dim; ++d) - v[d] = fetch[d][i]; + for (auto d = 0u; d < dim; ++d) v[d] = fetch[d][i]; self(bh::weight(fetch_weight[i]), span{v, dim}); } - } - else { + } else { for (auto i = 0l; i < n; ++i) { - for (auto d = 0u; d < dim; ++d) - v[d] = fetch[d][i]; + for (auto d = 0u; d < dim; ++d) v[d] = fetch[d][i]; self(span{v, dim}); } } @@ -318,20 +316,20 @@ bp::object histogram_getitem(const pyhistogram& self, bp::object args) { if (dim > BOOST_HISTOGRAM_AXIS_LIMIT) { PyErr_SetString(PyExc_RuntimeError, - bh::detail::cat("too many arguments, maximum is ", - BOOST_HISTOGRAM_AXIS_LIMIT).c_str()); + bh::detail::cat("too many arguments, maximum is ", + BOOST_HISTOGRAM_AXIS_LIMIT) + .c_str()); bp::throw_error_already_set(); } int idx[BOOST_HISTOGRAM_AXIS_LIMIT]; - for (unsigned i = 0; i < dim; ++i) - idx[i] = bp::extract(args[i]); + for (unsigned i = 0; i < dim; ++i) idx[i] = bp::extract(args[i]); return bp::object(self.at(span{idx, self.dim()})); } bp::object histogram_at(bp::tuple args, bp::dict kwargs) { - const pyhistogram & self = bp::extract(args[0]); + const pyhistogram& self = bp::extract(args[0]); if (kwargs) { PyErr_SetString(PyExc_RuntimeError, "no keyword arguments allowed"); @@ -343,14 +341,15 @@ bp::object histogram_at(bp::tuple args, bp::dict kwargs) { } bp::object histogram_reduce_to(bp::tuple args, bp::dict kwargs) { - const pyhistogram &self = bp::extract(args[0]); + const pyhistogram& self = bp::extract(args[0]); const unsigned nargs = bp::len(args) - 1; if (nargs > BOOST_HISTOGRAM_AXIS_LIMIT) { PyErr_SetString(PyExc_RuntimeError, - bh::detail::cat("too many arguments, maximum is ", - BOOST_HISTOGRAM_AXIS_LIMIT).c_str()); + bh::detail::cat("too many arguments, maximum is ", + BOOST_HISTOGRAM_AXIS_LIMIT) + .c_str()); bp::throw_error_already_set(); } @@ -360,84 +359,86 @@ bp::object histogram_reduce_to(bp::tuple args, bp::dict kwargs) { } int idx[BOOST_HISTOGRAM_AXIS_LIMIT]; - for (auto i = 0u; i < nargs; ++i) - idx[i] = bp::extract(args[1 + i]); + for (auto i = 0u; i < nargs; ++i) idx[i] = bp::extract(args[1 + i]); return bp::object(self.reduce_to(idx, idx + nargs)); } -std::string histogram_repr(const pyhistogram &h) { +std::string histogram_repr(const pyhistogram& h) { return bh::detail::cat(h); } -double element_value(const pyhistogram::element_type& b) { - return b.value(); -} +double element_value(const pyhistogram::element_type& b) { return b.value(); } double element_variance(const pyhistogram::element_type& b) { return b.variance(); } double element_getitem(const pyhistogram::element_type& e, int i) { - if (i < 0 || i > 1) - throw std::out_of_range("element_getitem"); + if (i < 0 || i > 1) throw std::out_of_range("element_getitem"); return i == 0 ? e.value() : e.variance(); } int element_len(const pyhistogram::element_type&) { return 2; } std::string element_repr(const pyhistogram::element_type& e) { - return bh::detail::cat("histogram.element(", e.value(), ", ", e.variance(), ")"); + return bh::detail::cat("histogram.element(", e.value(), ", ", e.variance(), + ")"); } void register_histogram() { bp::docstring_options dopt(true, true, false); - bp::scope s = bp::class_>( - "histogram", "N-dimensional histogram for real-valued data.", bp::no_init) - .def("__init__", bp::raw_function(histogram_init), - ":param axis args: axis objects" - "\nPass one or more axis objects to configure the histogram.") - // shadowed C++ ctors - .def(bp::init()) - // .def(bp::init()) + bp::scope s = + bp::class_>( + "histogram", "N-dimensional histogram for real-valued data.", + bp::no_init) + .def("__init__", bp::raw_function(histogram_init), + ":param axis args: axis objects" + "\nPass one or more axis objects to configure the histogram.") + // shadowed C++ ctors + .def(bp::init()) +// .def(bp::init()) #ifdef HAVE_NUMPY - .add_property("__array_interface__", &bp::access::array_interface) + .add_property("__array_interface__", &bp::access::array_interface) #endif - .add_property("dim", &pyhistogram::dim) - .def("axis", histogram_axis, bp::arg("i") = 0, - ":param int i: axis index" - "\n:return: corresponding axis object") - .def("__call__", bp::raw_function(histogram_fill), - ":param double args: values (number must match dimension)" - "\n:keyword double weight: optional weight" - "\n" - "\nIf Numpy support is enabled, 1d-arrays can be passed instead of" - "\nvalues, which must be equal in lenght. Arrays and values can" - "\nbe mixed arbitrarily in the same call.") - .def("__len__", &pyhistogram::size, - ":return: total number of bins, including under- and overflow") - .def("at", bp::raw_function(histogram_at), - ":param int args: indices of the bin (number must match dimension)" - "\n:return: bin content") - .def("__getitem__", histogram_getitem, - ":param int args: indices of the bin (number must match dimension)" - "\n:return: bin content") - .def("reduce_to", bp::raw_function(histogram_reduce_to), - ":param int args: indices of the axes in the reduced histogram" - "\n:return: reduced histogram with subset of axes") - .def("__iter__", bp::iterator()) - .def("__repr__", histogram_repr, - ":return: string representation of the histogram") - .def(bp::self == bp::self) - .def(bp::self != bp::self) - .def(bp::self += bp::self) - .def(bp::self *= double()) - .def(bp::self * double()) - .def(double() * bp::self) - .def(bp::self + bp::self) - .def_pickle(bh::serialization_suite()) - ; + .add_property("dim", &pyhistogram::dim) + .def("axis", histogram_axis, bp::arg("i") = 0, + ":param int i: axis index" + "\n:return: corresponding axis object") + .def( + "__call__", bp::raw_function(histogram_fill), + ":param double args: values (number must match dimension)" + "\n:keyword double weight: optional weight" + "\n" + "\nIf Numpy support is enabled, 1d-arrays can be passed " + "instead of" + "\nvalues, which must be equal in lenght. Arrays and values can" + "\nbe mixed arbitrarily in the same call.") + .def("__len__", &pyhistogram::size, + ":return: total number of bins, including under- and overflow") + .def("at", bp::raw_function(histogram_at), + ":param int args: indices of the bin (number must match " + "dimension)" + "\n:return: bin content") + .def("__getitem__", histogram_getitem, + ":param int args: indices of the bin (number must match " + "dimension)" + "\n:return: bin content") + .def("reduce_to", bp::raw_function(histogram_reduce_to), + ":param int args: indices of the axes in the reduced histogram" + "\n:return: reduced histogram with subset of axes") + .def("__iter__", bp::iterator()) + .def("__repr__", histogram_repr, + ":return: string representation of the histogram") + .def(bp::self == bp::self) + .def(bp::self != bp::self) + .def(bp::self += bp::self) + .def(bp::self *= double()) + .def(bp::self * double()) + .def(double() * bp::self) + .def(bp::self + bp::self) + .def_pickle(bh::serialization_suite()); bp::class_( "element", "Holds value and variance of bin count.", @@ -453,6 +454,5 @@ void register_histogram() { .def(bp::self + bp::self) .def(bp::self + double()) .def(double() + bp::self) - .def("__repr__", element_repr) - ; + .def("__repr__", element_repr); } diff --git a/src/python/module.cpp b/src/python/module.cpp index edf440cc6..c57ea2e28 100644 --- a/src/python/module.cpp +++ b/src/python/module.cpp @@ -5,10 +5,10 @@ // or copy at http://www.boost.org/LICENSE_1_0.txt) #include -#include #include +#include #ifdef HAVE_NUMPY -# include +#include #endif void register_axis_types(); @@ -23,9 +23,7 @@ BOOST_PYTHON_MODULE(histogram) { #else current.attr("HAVE_NUMPY") = false; #endif - object axis_module = object( - borrowed(PyImport_AddModule("histogram.axis")) - ); + object axis_module = object(borrowed(PyImport_AddModule("histogram.axis"))); current.attr("axis") = axis_module; { scope current = axis_module; diff --git a/src/python/serialization_suite.hpp b/src/python/serialization_suite.hpp index 870b75a09..0e6327088 100644 --- a/src/python/serialization_suite.hpp +++ b/src/python/serialization_suite.hpp @@ -31,11 +31,11 @@ namespace detail { class python_bytes_sink : public iostreams::sink { public: - python_bytes_sink(PyObject **pstr) : pstr_(pstr), len_(0), pos_(0) { + python_bytes_sink(PyObject** pstr) : pstr_(pstr), len_(0), pos_(0) { BOOST_ASSERT(*pstr == 0); } - std::streamsize write(const char *s, std::streamsize n) { + std::streamsize write(const char* s, std::streamsize n) { if (len_ == 0) { *pstr_ = PyBytes_FromStringAndSize(s, n); if (*pstr_ == 0) // no point trying to recover from allocation error @@ -47,7 +47,7 @@ class python_bytes_sink : public iostreams::sink { if (_PyBytes_Resize(pstr_, len_) == -1) std::abort(); // no point trying to recover from allocation error } - char *b = PyBytes_AS_STRING(*pstr_); + char* b = PyBytes_AS_STRING(*pstr_); std::copy(s, s + n, b + pos_); } pos_ += n; @@ -55,17 +55,18 @@ class python_bytes_sink : public iostreams::sink { } private: - PyObject **pstr_; + PyObject** pstr_; std::streamsize len_, pos_; }; } // namespace detail -template struct serialization_suite : python::pickle_suite { +template +struct serialization_suite : python::pickle_suite { static python::tuple getstate(python::object obj) { - PyObject *pobj = 0; + PyObject* pobj = 0; iostreams::stream os(&pobj); archive::text_oarchive oa(os); - oa << python::extract(obj)(); + oa << python::extract(obj)(); os.flush(); return python::make_tuple(obj.attr("__dict__"), python::object(python::handle<>(pobj))); @@ -81,7 +82,7 @@ template struct serialization_suite : python::pickle_suite { iostreams::stream is(PyBytes_AS_STRING(o.ptr()), PyBytes_Size(o.ptr())); archive::text_iarchive ia(is); - ia >> python::extract(obj)(); + ia >> python::extract(obj)(); } static bool getstate_manages_dict() { return true; } diff --git a/src/python/utility.hpp b/src/python/utility.hpp index 567228126..2ad168ca3 100644 --- a/src/python/utility.hpp +++ b/src/python/utility.hpp @@ -8,22 +8,22 @@ #define _BOOST_HISTOGRAM_PYTHON_UTILITY_HPP_ #include -#include #include +#include namespace boost { namespace python { template str dtype_typestr() { - str s; - if (std::is_floating_point::value) - s = "|f"; - else if (std::is_integral::value) - s = std::is_unsigned::value ? "|u" : "|i"; - else - throw std::invalid_argument("T must be a builtin arithmetic type"); - s += str(sizeof(T)); - return s; + str s; + if (std::is_floating_point::value) + s = "|f"; + else if (std::is_integral::value) + s = std::is_unsigned::value ? "|u" : "|i"; + else + throw std::invalid_argument("T must be a builtin arithmetic type"); + s += str(sizeof(T)); + return s; } } // python } // boost diff --git a/test/adaptive_storage_test.cpp b/test/adaptive_storage_test.cpp index f34933ea0..bb23b7615 100644 --- a/test/adaptive_storage_test.cpp +++ b/test/adaptive_storage_test.cpp @@ -18,18 +18,21 @@ using namespace boost::histogram; -template adaptive_storage prepare(std::size_t n) { +template +adaptive_storage prepare(std::size_t n) { auto a = detail::array(n); return adaptive_storage(a); } -template adaptive_storage prepare(std::size_t n, const T x) { +template +adaptive_storage prepare(std::size_t n, const T x) { auto a = detail::array(n); a[0] = x; return adaptive_storage(a); } -template void copy_impl() { +template +void copy_impl() { const auto b = prepare(1); auto a(b); BOOST_TEST(a == b); @@ -47,7 +50,8 @@ template void copy_impl() { } #ifdef HAVE_SERIALIZATION -template void serialization_impl() { +template +void serialization_impl() { const auto a = prepare(1, T(1)); std::ostringstream os; std::string buf; @@ -67,7 +71,8 @@ template void serialization_impl() { BOOST_TEST(a == b); } -template <> void serialization_impl() { +template <> +void serialization_impl() { adaptive_storage a(std::size_t(1)); std::ostringstream os; std::string buf; @@ -88,7 +93,8 @@ template <> void serialization_impl() { } #endif -template void equal_impl() { +template +void equal_impl() { adaptive_storage a(std::size_t(1)); auto b = prepare(1, T(0)); BOOST_TEST_EQ(a[0].value(), 0.0); @@ -104,7 +110,8 @@ template void equal_impl() { BOOST_TEST(!(c == d)); } -template <> void equal_impl() { +template <> +void equal_impl() { adaptive_storage a(std::size_t(1)); auto b = prepare(1, 0); auto c = prepare(2, 0); @@ -125,7 +132,8 @@ template <> void equal_impl() { BOOST_TEST(!(d == a)); } -template void increase_and_grow_impl() { +template +void increase_and_grow_impl() { auto tmax = std::numeric_limits::max(); auto s = prepare(2, tmax); auto n = s; @@ -145,7 +153,8 @@ template void increase_and_grow_impl() { BOOST_TEST_EQ(n2[1].value(), 0.0); } -template <> void increase_and_grow_impl() { +template <> +void increase_and_grow_impl() { adaptive_storage s(std::size_t(2)); BOOST_TEST_EQ(s[0].value(), 0); BOOST_TEST_EQ(s[1].value(), 0); @@ -154,7 +163,8 @@ template <> void increase_and_grow_impl() { BOOST_TEST_EQ(s[1].value(), 0); } -template void convert_array_storage_impl() { +template +void convert_array_storage_impl() { const auto aref = prepare(1, T(0)); array_storage s(std::size_t(1)); s.increase(0); @@ -180,8 +190,7 @@ template void convert_array_storage_impl() { array_storage t(std::size_t(1)); t.increase(0); - while (t[0] < 1e20) - t.add(0, t[0]); + while (t[0] < 1e20) t.add(0, t[0]); auto d = aref; d = t; BOOST_TEST(d == t); @@ -213,7 +222,8 @@ template void convert_array_storage_impl() { BOOST_TEST(h == u); } -template <> void convert_array_storage_impl() { +template <> +void convert_array_storage_impl() { const auto aref = adaptive_storage(std::size_t(1)); BOOST_TEST_EQ(aref[0].value(), 0.0); array_storage s(std::size_t(1)); @@ -238,7 +248,8 @@ template <> void convert_array_storage_impl() { BOOST_TEST(!(d == t)); } -template void add_impl() { +template +void add_impl() { auto a = prepare(2); auto b = prepare(2); if (std::is_same::value) { @@ -255,7 +266,8 @@ template void add_impl() { } } -template void add_impl_all_rhs() { +template +void add_impl_all_rhs() { add_impl(); add_impl(); add_impl(); diff --git a/test/axis_test.cpp b/test/axis_test.cpp index e31df8307..46945ccdb 100644 --- a/test/axis_test.cpp +++ b/test/axis_test.cpp @@ -21,7 +21,7 @@ using namespace boost::histogram; #define BOOST_TEST_IS_CLOSE(a, b, eps) BOOST_TEST(std::abs(a - b) < eps) template -void test_axis_iterator(const Axis &a, int begin, int end) { +void test_axis_iterator(const Axis& a, int begin, int end) { for (auto bin : a) { BOOST_TEST_EQ(bin.idx(), begin); BOOST_TEST_EQ(bin, a[begin]); @@ -62,7 +62,8 @@ int main() { { axis::regular<> a{4, -2, 2}; BOOST_TEST_EQ(a[-1].lower(), -std::numeric_limits::infinity()); - BOOST_TEST_EQ(a[a.size()].upper(), std::numeric_limits::infinity()); + BOOST_TEST_EQ(a[a.size()].upper(), + std::numeric_limits::infinity()); axis::regular<> b; BOOST_TEST_NOT(a == b); b = a; @@ -160,7 +161,8 @@ int main() { { axis::variable<> a{-1, 0, 1}; BOOST_TEST_EQ(a[-1].lower(), -std::numeric_limits::infinity()); - BOOST_TEST_EQ(a[a.size()].upper(), std::numeric_limits::infinity()); + BOOST_TEST_EQ(a[a.size()].upper(), + std::numeric_limits::infinity()); axis::variable<> b; BOOST_TEST_NOT(a == b); b = a; @@ -269,7 +271,8 @@ int main() { a6 = a1; BOOST_TEST_EQ(a6, a1); axis::any, axis::integer<>> a7(axis::integer<>(0, 2)); - BOOST_TEST_THROWS(axis::any> a8(a7), std::invalid_argument); + BOOST_TEST_THROWS(axis::any> a8(a7), + std::invalid_argument); BOOST_TEST_THROWS(a4 = a7, std::invalid_argument); } @@ -299,14 +302,13 @@ int main() { axes.push_back(axis::regular( 2, 1, 10, "regular4", axis::uoflow::off, -0.5)); axes.push_back(axis::circular<>(4, 0.1, 1.0, "polar")); - axes.push_back(axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off)); + axes.push_back( + axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off)); axes.push_back(axis::category<>({A, B, C}, "category")); axes.push_back(axis::category({a, b}, "category2")); axes.push_back(axis::integer<>(-1, 1, "integer", axis::uoflow::off)); std::ostringstream os; - for (const auto &a : axes) { - os << a << "\n"; - } + for (const auto& a : axes) { os << a << "\n"; } const std::string ref = "regular(2, -1, 1, label='regular1')\n" "regular_log(2, 1, 10, label='regular2', uoflow=False)\n" @@ -329,7 +331,7 @@ int main() { axes.push_back(axis::variable<>{-1, 0, 1}); axes.push_back(axis::category<>{A, B, C}); axes.push_back(axis::integer<>{-1, 1}); - for (const auto &a : axes) { + for (const auto& a : axes) { BOOST_TEST(!(a == axis::any_std())); BOOST_TEST_EQ(a, a); } @@ -342,7 +344,7 @@ int main() { std::string a = "A", b = "B"; axis::any_std x = axis::category({a, b}, "category"); BOOST_TEST_THROWS(x.index(1.5), std::runtime_error); - const auto &cx = axis::cast>(x); + const auto& cx = axis::cast>(x); BOOST_TEST_EQ(cx.index(b), 1); } @@ -354,7 +356,8 @@ int main() { std_vector1 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1}, axis::category<>{A, B, C}}; - std::vector, axis::variable<>, axis::category<>>> + std::vector< + axis::any, axis::variable<>, axis::category<>>> std_vector2 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1}, axis::category<>{{A, B, C}}}; @@ -376,8 +379,8 @@ int main() { std::make_tuple(axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1}, axis::category<>{{A, B}}); - auto tuple3 = - std::make_tuple(axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1}); + auto tuple3 = std::make_tuple(axis::regular<>{2, -1, 1}, + axis::variable<>{-1, 0, 1}); BOOST_TEST(detail::axes_equal(std_vector1, tuple1)); BOOST_TEST(detail::axes_equal(tuple1, std_vector1)); @@ -394,7 +397,8 @@ int main() { std_vector1 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1}, axis::category<>{A, B, C}}; - std::vector, axis::variable<>, axis::category<>>> + std::vector< + axis::any, axis::variable<>, axis::category<>>> std_vector2 = {axis::regular<>{2, -2, 2}, axis::variable<>{-2, 0, 2}, axis::category<>{A, B}}; diff --git a/test/detail_test.cpp b/test/detail_test.cpp index d6ce84f2b..0a5686a40 100644 --- a/test/detail_test.cpp +++ b/test/detail_test.cpp @@ -29,21 +29,24 @@ using i2 = mp11::mp_int<2>; using i3 = mp11::mp_int<3>; namespace std { // never add to std, we only do it to get ADL working -template ostream &operator<<(ostream &os, const vector &v) { +template +ostream& operator<<(ostream& os, const vector& v) { os << "[ "; - for (const auto &x : v) - os << x << " "; + for (const auto& x : v) os << x << " "; os << "]"; return os; } struct ostreamer { - ostream &os; - template void operator()(const T &t) const { os << t << " "; } + ostream& os; + template + void operator()(const T& t) const { + os << t << " "; + } }; template -ostream &operator<<(ostream &os, const tuple &t) { +ostream& operator<<(ostream& os, const tuple& t) { os << "[ "; ::boost::mp11::tuple_for_each(t, ostreamer{os}); os << "]"; @@ -135,16 +138,16 @@ int main() { struct no_methods {}; struct value_method { - const double &value() const; + const double& value() const; }; struct variance_method { - const double &variance() const; + const double& variance() const; }; struct value_and_variance_methods { - const double &value() const; - const double &variance() const; + const double& value() const; + const double& variance() const; }; BOOST_TEST_EQ(has_variance_support(), false); @@ -158,19 +161,19 @@ int main() { using result1 = classify_container; BOOST_TEST_TRAIT_TRUE((std::is_same)); - using result1a = classify_container; + using result1a = classify_container; BOOST_TEST_TRAIT_TRUE((std::is_same)); using result2 = classify_container>; BOOST_TEST_TRAIT_TRUE((std::is_same)); - using result2a = classify_container &>; + using result2a = classify_container&>; BOOST_TEST_TRAIT_TRUE((std::is_same)); using result3 = classify_container>; BOOST_TEST_TRAIT_TRUE((std::is_same)); - using result3a = classify_container &>; + using result3a = classify_container&>; BOOST_TEST_TRAIT_TRUE((std::is_same)); using result4 = classify_container; @@ -190,10 +193,10 @@ int main() { { using T1 = int; using T2 = const int; - using T3 = const int &; + using T3 = const int&; using T4 = volatile int; using T5 = volatile const int; - using T6 = volatile const int &; + using T6 = volatile const int&; BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); @@ -205,9 +208,9 @@ int main() { // mp_union { using L1 = mp11::mp_list; - using L2 = mp11::mp_list; + using L2 = mp11::mp_list; using result = mp_union; - using expected = mp11::mp_list; + using expected = mp11::mp_list; BOOST_TEST_TRAIT_TRUE((std::is_same)); } diff --git a/test/fail_histogram_dynamic_bin_2_test.cpp b/test/fail_histogram_dynamic_bin_2_test.cpp index 4318caaf7..9993558a7 100644 --- a/test/fail_histogram_dynamic_bin_2_test.cpp +++ b/test/fail_histogram_dynamic_bin_2_test.cpp @@ -3,6 +3,7 @@ using namespace boost::histogram; int main() { - auto h = make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); + auto h = + make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); h.at(std::make_pair(-2, 0)); } diff --git a/test/fail_histogram_dynamic_bin_3_test.cpp b/test/fail_histogram_dynamic_bin_3_test.cpp index f4a09ba13..26a5f8962 100644 --- a/test/fail_histogram_dynamic_bin_3_test.cpp +++ b/test/fail_histogram_dynamic_bin_3_test.cpp @@ -3,6 +3,7 @@ using namespace boost::histogram; int main() { - auto h = make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); + auto h = + make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); h.at(std::vector({-2, 0})); } diff --git a/test/fail_histogram_static_bin_vector_out_of_bounds_test.cpp b/test/fail_histogram_static_bin_vector_out_of_bounds_test.cpp index 082ac1816..e2ec51199 100644 --- a/test/fail_histogram_static_bin_vector_out_of_bounds_test.cpp +++ b/test/fail_histogram_static_bin_vector_out_of_bounds_test.cpp @@ -3,6 +3,7 @@ using namespace boost::histogram; int main() { - auto h = make_static_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); + auto h = + make_static_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2)); h.at(std::vector(-2, 0)); } diff --git a/test/histogram_test.cpp b/test/histogram_test.cpp index 9ef138ad3..b97d35392 100644 --- a/test/histogram_test.cpp +++ b/test/histogram_test.cpp @@ -33,13 +33,13 @@ using namespace boost::histogram::literals; // to get _c suffix namespace mp11 = boost::mp11; template -auto make_histogram(static_tag, Axes &&... axes) +auto make_histogram(static_tag, Axes&&... axes) -> decltype(make_static_histogram_with(std::forward(axes)...)) { return make_static_histogram_with(std::forward(axes)...); } template -auto make_histogram(dynamic_tag, Axes &&... axes) +auto make_histogram(dynamic_tag, Axes&&... axes) -> decltype(make_dynamic_histogram_with(std::forward(axes)...)) { return make_dynamic_histogram_with(std::forward(axes)...); } @@ -51,15 +51,16 @@ int expected_moved_from_dim(static_tag, int static_value) { int expected_moved_from_dim(dynamic_tag, int) { return 0; } template -typename Histogram::element_type sum(const Histogram &h) { +typename Histogram::element_type sum(const Histogram& h) { return std::accumulate(h.begin(), h.end(), typename Histogram::element_type(0)); } template -void pass_histogram(boost::histogram::histogram &) {} +void pass_histogram(boost::histogram::histogram&) {} -template void run_tests() { +template +void run_tests() { // init_1 { @@ -76,8 +77,8 @@ template void run_tests() { // init_2 { - auto h = make_histogram(Type(), axis::regular<>{3, -1, 1}, - axis::integer<>{-1, 2}); + auto h = make_histogram( + Type(), axis::regular<>{3, -1, 1}, axis::integer<>{-1, 2}); BOOST_TEST_EQ(h.dim(), 2); BOOST_TEST_EQ(h.size(), 25); BOOST_TEST_EQ(h.axis(0_c).shape(), 5); @@ -89,9 +90,9 @@ template void run_tests() { // init_3 { - auto h = make_histogram(Type(), axis::regular<>{3, -1, 1}, - axis::integer<>{-1, 2}, - axis::circular<>{3}); + auto h = make_histogram( + Type(), axis::regular<>{3, -1, 1}, axis::integer<>{-1, 2}, + axis::circular<>{3}); BOOST_TEST_EQ(h.dim(), 3); BOOST_TEST_EQ(h.size(), 75); auto h2 = make_histogram>( @@ -136,8 +137,9 @@ template void run_tests() { h(0, 0); auto h2 = decltype(h)(h); BOOST_TEST(h2 == h); - auto h3 = static_histogram, axis::integer<>>, - array_storage>(h); + auto h3 = + static_histogram, axis::integer<>>, + array_storage>(h); BOOST_TEST_EQ(h3, h); } @@ -153,8 +155,9 @@ template void run_tests() { // test self-assign h2 = h2; BOOST_TEST_EQ(h, h2); - auto h3 = static_histogram, axis::integer<>>, - array_storage>(); + auto h3 = + static_histogram, axis::integer<>>, + array_storage>(); h3 = h; BOOST_TEST_EQ(h, h3); } @@ -183,8 +186,8 @@ template void run_tests() { // axis methods { enum { A = 3, B = 5 }; - auto a = make_histogram(Type(), - axis::regular<>(1, 1, 2, "foo")); + auto a = make_histogram( + Type(), axis::regular<>(1, 1, 2, "foo")); BOOST_TEST_EQ(a.axis().size(), 1); BOOST_TEST_EQ(a.axis().shape(), 3); BOOST_TEST_EQ(a.axis().index(1), 0); @@ -203,7 +206,8 @@ template void run_tests() { b.axis().label("foo"); BOOST_TEST_EQ(b.axis().label(), "foo"); - auto c = make_histogram(Type(), axis::category<>({A, B})); + auto c = + make_histogram(Type(), axis::category<>({A, B})); BOOST_TEST_EQ(c.axis().size(), 2); BOOST_TEST_EQ(c.axis().shape(), 2); BOOST_TEST_EQ(c.axis().index(A), 0); @@ -227,7 +231,8 @@ template void run_tests() { BOOST_TEST(c != b); BOOST_TEST(a == c); BOOST_TEST(c == a); - auto d = make_histogram(Type(), axis::regular<>(2, 0, 1)); + auto d = + make_histogram(Type(), axis::regular<>(2, 0, 1)); BOOST_TEST(c != d); BOOST_TEST(d != c); c(0); @@ -425,8 +430,8 @@ template void run_tests() { // add_1 { auto a = make_histogram(Type(), axis::integer<>(0, 2)); - auto b = - make_histogram>(Type(), axis::integer<>(0, 2)); + auto b = make_histogram>(Type(), + axis::integer<>(0, 2)); a(0); // 1 0 b(1); // 0 1 auto a2 = a; @@ -477,8 +482,8 @@ template void run_tests() { { auto a = make_histogram>(Type(), axis::integer<>(-1, 2)); - auto b = - make_histogram>(Type(), axis::integer<>(-1, 2)); + auto b = make_histogram>(Type(), + axis::integer<>(-1, 2)); a(-1); b(1); auto c = a; @@ -578,10 +583,11 @@ template void run_tests() { Type(), axis::regular<>(3, -1, 1, "r"), axis::integer<>(0, 2, "i")); std::ostringstream os; os << a; - BOOST_TEST_EQ(os.str(), "histogram(" - "\n regular(3, -1, 1, label='r')," - "\n integer(0, 2, label='i')," - "\n)"); + BOOST_TEST_EQ(os.str(), + "histogram(" + "\n regular(3, -1, 1, label='r')," + "\n integer(0, 2, label='i')," + "\n)"); } // histogram_reset @@ -701,7 +707,7 @@ template void run_tests() { // custom axis { struct custom_axis : public axis::integer<> { - using value_type = const char *; // type that is fed to the axis + using value_type = const char*; // type that is fed to the axis using integer::integer; // inherit ctors of base @@ -727,7 +733,7 @@ template void run_tests() { // histogram iterator 1D { auto h = make_histogram(Type(), axis::integer<>(0, 3)); - const auto &a = h.axis(); + const auto& a = h.axis(); h(weight(2), 0); h(1); h(1); @@ -763,8 +769,8 @@ template void run_tests() { auto h = make_histogram( Type(), axis::integer<>(0, 1), axis::integer<>(2, 4, "", axis::uoflow::off)); - const auto &a0 = h.axis(0_c); - const auto &a1 = h.axis(1_c); + const auto& a0 = h.axis(0_c); + const auto& a1 = h.axis(1_c); h(weight(2), 0, 2); h(-1, 2); h(1, 3); @@ -824,8 +830,7 @@ template void run_tests() { // STL compatibility { auto h = make_histogram(Type(), axis::integer<>(0, 3)); - for (int i = 0; i < 3; ++i) - h(i); + for (int i = 0; i < 3; ++i) h(i); auto a = std::vector>(); std::partial_sum(h.begin(), h.end(), std::back_inserter(a)); BOOST_TEST_EQ(a[0].value(), 1); @@ -890,14 +895,15 @@ template void run_tests() { } } -template void run_mixed_tests() { +template +void run_mixed_tests() { // compare { auto a = make_histogram(T1{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2)); - auto b = make_histogram>(T2{}, axis::regular<>{3, 0, 3}, - axis::integer<>(0, 2)); + auto b = make_histogram>( + T2{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2)); BOOST_TEST_EQ(a, b); auto b2 = make_histogram(T2{}, axis::integer<>{0, 3}, axis::integer<>(0, 2)); @@ -926,8 +932,8 @@ template void run_mixed_tests() { { auto a = make_histogram(T1{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2)); - auto b = make_histogram>(T2{}, axis::regular<>{3, 0, 3}, - axis::integer<>(0, 2)); + auto b = make_histogram>( + T2{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2)); a(1, 1); BOOST_TEST_NE(a, b); b = a; @@ -1000,7 +1006,7 @@ int main() { // histogram iterator { auto h = make_dynamic_histogram(axis::integer<>(0, 3)); - const auto &a = h.axis(); + const auto& a = h.axis(); h(weight(2), 0); h(1); h(1); diff --git a/test/speed_cpp.cpp b/test/speed_cpp.cpp index 9519eeeb5..838c63106 100644 --- a/test/speed_cpp.cpp +++ b/test/speed_cpp.cpp @@ -6,12 +6,12 @@ #include #include +#include #include #include #include -#include #include -#include +#include using namespace boost::histogram; using boost::mp11::mp_list; @@ -21,17 +21,16 @@ std::unique_ptr random_array(unsigned n, int type) { std::default_random_engine gen(1); if (type) { // type == 1 std::normal_distribution<> d(0.5, 0.3); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } else { // type == 0 std::uniform_real_distribution<> d(0.0, 1.0); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } return r; } -template void ignore( const T& ) { } +template +void ignore(const T&) {} double baseline(unsigned n) { auto r = random_array(n, 0); @@ -49,15 +48,15 @@ double baseline(unsigned n) { return best; } -template double compare_1d(unsigned n, int distrib) { +template +double compare_1d(unsigned n, int distrib) { auto r = random_array(n, distrib); auto best = std::numeric_limits::max(); for (unsigned k = 0; k < 20; ++k) { auto h = Histogram(axis::regular<>(100, 0, 1)); auto t = clock(); - for (unsigned i = 0; i < n; ++i) - h(r[i]); + for (unsigned i = 0; i < n; ++i) h(r[i]); t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); } @@ -65,15 +64,16 @@ template double compare_1d(unsigned n, int distrib) { return best; } -template double compare_2d(unsigned n, int distrib) { +template +double compare_2d(unsigned n, int distrib) { auto r = random_array(n, distrib); auto best = std::numeric_limits::max(); for (unsigned k = 0; k < 20; ++k) { - auto h = Histogram(axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1)); + auto h = + Histogram(axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1)); auto t = clock(); - for (unsigned i = 0; i < n/2; ++i) - h(r[2 * i], r[2 * i + 1]); + for (unsigned i = 0; i < n / 2; ++i) h(r[2 * i], r[2 * i + 1]); t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); } @@ -81,7 +81,8 @@ template double compare_2d(unsigned n, int distrib) { return best; } -template double compare_3d(unsigned n, int distrib) { +template +double compare_3d(unsigned n, int distrib) { auto r = random_array(n, distrib); auto best = std::numeric_limits::max(); @@ -89,7 +90,7 @@ template double compare_3d(unsigned n, int distrib) { auto h = Histogram(axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1)); auto t = clock(); - for (unsigned i = 0; i < n/3; ++i) + for (unsigned i = 0; i < n / 3; ++i) h(r[3 * i], r[3 * i + 1], r[3 * i + 2]); t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); @@ -98,7 +99,8 @@ template double compare_3d(unsigned n, int distrib) { return best; } -template double compare_6d(unsigned n, int distrib) { +template +double compare_6d(unsigned n, int distrib) { auto r = random_array(n, distrib); auto best = std::numeric_limits::max(); @@ -108,9 +110,9 @@ template double compare_6d(unsigned n, int distrib) { axis::regular<>(10, 0, 1), axis::regular<>(10, 0, 1)); auto t = clock(); - for (unsigned i = 0; i < n/6; ++i) { - h(r[6 * i], r[6 * i + 1], r[6 * i + 2], - r[6 * i + 3], r[6 * i + 4], r[6 * i + 5]); + for (unsigned i = 0; i < n / 6; ++i) { + h(r[6 * i], r[6 * i + 1], r[6 * i + 2], r[6 * i + 3], r[6 * i + 4], + r[6 * i + 5]); } t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); @@ -132,14 +134,13 @@ int main() { printf("normal distribution\n"); printf("hs_ss %.3f\n", compare_1d>, - array_storage>>( - nfill, itype)); + array_storage>>(nfill, itype)); printf("hs_sd %.3f\n", - compare_1d>, - adaptive_storage>>(nfill, itype)); + compare_1d< + static_histogram>, adaptive_storage>>( + nfill, itype)); printf("hd_ss %.3f\n", - compare_1d>>( + compare_1d>>( nfill, itype)); printf("hd_sd %.3f\n", compare_1d>( @@ -152,17 +153,16 @@ int main() { printf("uniform distribution\n"); else printf("normal distribution\n"); - printf("hs_ss %.3f\n", - compare_2d, axis::regular<>>, - array_storage>>(nfill, itype)); - printf("hs_sd %.3f\n", - compare_2d, axis::regular<>>, - adaptive_storage>>(nfill, itype)); + printf( + "hs_ss %.3f\n", + compare_2d, axis::regular<>>, + array_storage>>(nfill, itype)); + printf( + "hs_sd %.3f\n", + compare_2d, axis::regular<>>, + adaptive_storage>>(nfill, itype)); printf("hd_ss %.3f\n", - compare_2d>>( + compare_2d>>( nfill, itype)); printf("hd_sd %.3f\n", compare_2d>( @@ -184,8 +184,7 @@ int main() { mp_list, axis::regular<>, axis::regular<>>, adaptive_storage>>(nfill, itype)); printf("hd_ss %.3f\n", - compare_3d>>( + compare_3d>>( nfill, itype)); printf("hd_sd %.3f\n", compare_3d>( @@ -201,16 +200,15 @@ int main() { printf("hs_ss %.3f\n", compare_6d, axis::regular<>, axis::regular<>, - axis::regular<>, axis::regular<>, axis::regular<>>, + axis::regular<>, axis::regular<>, axis::regular<>>, array_storage>>(nfill, itype)); printf("hs_sd %.3f\n", compare_6d, axis::regular<>, axis::regular<>, - axis::regular<>, axis::regular<>, axis::regular<>>, + axis::regular<>, axis::regular<>, axis::regular<>>, adaptive_storage>>(nfill, itype)); printf("hd_ss %.3f\n", - compare_6d>>( + compare_6d>>( nfill, itype)); printf("hd_sd %.3f\n", compare_6d>( diff --git a/test/speed_gsl.cpp b/test/speed_gsl.cpp index f6bb0357d..b333df2a8 100644 --- a/test/speed_gsl.cpp +++ b/test/speed_gsl.cpp @@ -11,20 +11,18 @@ #include #include #include -#include #include +#include std::unique_ptr random_array(unsigned n, int type) { std::unique_ptr r(new double[n]); std::default_random_engine gen(1); if (type) { // type == 1 std::normal_distribution<> d(0.5, 0.3); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } else { // type == 0 std::uniform_real_distribution<> d(0.0, 1.0); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } return r; } @@ -34,11 +32,10 @@ void compare_1d(unsigned n, int distrib) { double best = std::numeric_limits::max(); for (unsigned k = 0; k < 20; ++k) { - gsl_histogram *h = gsl_histogram_alloc(100); + gsl_histogram* h = gsl_histogram_alloc(100); gsl_histogram_set_ranges_uniform(h, 0, 1); auto t = clock(); - for (unsigned i = 0; i < n; ++i) - gsl_histogram_increment(h, r[i]); + for (unsigned i = 0; i < n; ++i) gsl_histogram_increment(h, r[i]); t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); gsl_histogram_free(h); @@ -51,10 +48,10 @@ void compare_2d(unsigned n, int distrib) { double best = std::numeric_limits::max(); for (unsigned k = 0; k < 20; ++k) { - gsl_histogram2d *h = gsl_histogram2d_alloc(100, 100); + gsl_histogram2d* h = gsl_histogram2d_alloc(100, 100); gsl_histogram2d_set_ranges_uniform(h, 0, 1, 0, 1); auto t = clock(); - for (unsigned i = 0; i < n/2; ++i) + for (unsigned i = 0; i < n / 2; ++i) gsl_histogram2d_increment(h, r[2 * i], r[2 * i + 1]); t = clock() - t; best = std::min(best, double(t) / CLOCKS_PER_SEC); @@ -63,7 +60,7 @@ void compare_2d(unsigned n, int distrib) { printf("gsl %.3f\n", best); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { constexpr unsigned nfill = 6000000; printf("1D\n"); printf("uniform distribution\n"); diff --git a/test/speed_root.cpp b/test/speed_root.cpp index 06e3a4245..dca1c6cfe 100644 --- a/test/speed_root.cpp +++ b/test/speed_root.cpp @@ -13,20 +13,18 @@ #include #include #include -#include #include +#include std::unique_ptr random_array(unsigned n, int type) { std::unique_ptr r(new double[n]); std::default_random_engine gen(1); if (type) { // type == 1 std::normal_distribution<> d(0.5, 0.3); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } else { // type == 0 std::uniform_real_distribution<> d(0.0, 1.0); - for (unsigned i = 0; i < n; ++i) - r[i] = d(gen); + for (unsigned i = 0; i < n; ++i) r[i] = d(gen); } return r; } @@ -38,8 +36,7 @@ void compare_1d(unsigned n, int distrib) { for (unsigned k = 0; k < 20; ++k) { TH1I hroot("", "", 100, 0, 1); auto t = clock(); - for (unsigned i = 0; i < n; ++i) - hroot.Fill(r[i]); + for (unsigned i = 0; i < n; ++i) hroot.Fill(r[i]); t = clock() - t; best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC); } @@ -53,8 +50,7 @@ void compare_2d(unsigned n, int distrib) { for (unsigned k = 0; k < 20; ++k) { TH2I hroot("", "", 100, 0, 1, 100, 0, 1); auto t = clock(); - for (unsigned i = 0; i < n/2; ++i) - hroot.Fill(r[2 * i], r[2 * i + 1]); + for (unsigned i = 0; i < n / 2; ++i) hroot.Fill(r[2 * i], r[2 * i + 1]); t = clock() - t; best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC); } @@ -68,7 +64,7 @@ void compare_3d(unsigned n, int distrib) { for (unsigned k = 0; k < 20; ++k) { TH3I hroot("", "", 100, 0, 1, 100, 0, 1, 100, 0, 1); auto t = clock(); - for (unsigned i = 0; i < n/3; ++i) + for (unsigned i = 0; i < n / 3; ++i) hroot.Fill(r[3 * i], r[3 * i + 1], r[3 * i + 2]); t = clock() - t; best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC); @@ -87,16 +83,14 @@ void compare_6d(unsigned n, int distrib) { THnI hroot("", "", 6, &bin.front(), &min.front(), &max.front()); auto t = clock(); - for (unsigned i = 0; i < n/6; ++i) { - hroot.Fill(r.get() + 6 * i); - } + for (unsigned i = 0; i < n / 6; ++i) { hroot.Fill(r.get() + 6 * i); } t = clock() - t; best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC); } printf("root %.3f\n", best_root); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { constexpr unsigned nfill = 6000000; printf("1D\n");