// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs
// Based on "crates/store/re_sdk_types/definitions/rerun/archetypes/bar_chart.fbs".

#pragma once

#include "../collection.hpp"
#include "../component_batch.hpp"
#include "../component_column.hpp"
#include "../components/color.hpp"
#include "../components/length.hpp"
#include "../components/tensor_data.hpp"
#include "../result.hpp"

#include <cstdint>
#include <optional>
#include <utility>
#include <vector>

namespace rerun::archetypes {
    /// **Archetype**: A bar chart.
    ///
    /// The bar heights will be the provided values, and the x coordinates of the bars will be the provided abscissa or default to the index of the provided values.
    ///
    /// ## Example
    ///
    /// ### Simple bar chart
    /// ![image](https://static.rerun.io/bar_chart/ba274527813ccb9049f6760d82f36c8da6a6f2ff/full.png)
    ///
    /// ```cpp
    /// #include <rerun.hpp>
    /// #include <vector>
    ///
    /// int main() {
    ///     const auto rec = rerun::RecordingStream("rerun_example_bar_chart");
    ///     rec.spawn().exit_on_failure();
    ///
    ///     rec.log("bar_chart", rerun::BarChart::i64({8, 4, 0, 9, 1, 4, 1, 6, 9, 0}));
    ///
    ///     auto abscissa = std::vector<int64_t>{0, 1, 3, 4, 7, 11};
    ///     auto abscissa_data = rerun::TensorData(rerun::Collection{abscissa.size()}, abscissa);
    ///     rec.log(
    ///         "bar_chart_custom_abscissa",
    ///         rerun::BarChart::i64({8, 4, 0, 9, 1, 4}).with_abscissa(abscissa_data)
    ///     );
    ///
    ///     auto widths = std::vector<float>{1, 2, 1, 3, 4, 1};
    ///     rec.log(
    ///         "bar_chart_custom_abscissa_and_widths",
    ///         rerun::BarChart::i64({8, 4, 0, 9, 1, 4}).with_abscissa(abscissa_data).with_widths(widths)
    ///     );
    /// }
    /// ```
    struct BarChart {
        /// The values. Should always be a 1-dimensional tensor (i.e. a vector).
        std::optional<ComponentBatch> values;

        /// The color of the bar chart
        std::optional<ComponentBatch> color;

        /// The abscissa corresponding to each value. Should be a 1-dimensional tensor (i.e. a vector) in same length as values.
        std::optional<ComponentBatch> abscissa;

        /// The width of the bins, defined in x-axis units and defaults to 1. Should be a 1-dimensional tensor (i.e. a vector) in same length as values.
        std::optional<ComponentBatch> widths;

      public:
        /// The name of the archetype as used in `ComponentDescriptor`s.
        static constexpr const char ArchetypeName[] = "rerun.archetypes.BarChart";

        /// `ComponentDescriptor` for the `values` field.
        static constexpr auto Descriptor_values = ComponentDescriptor(
            ArchetypeName, "BarChart:values", Loggable<rerun::components::TensorData>::ComponentType
        );
        /// `ComponentDescriptor` for the `color` field.
        static constexpr auto Descriptor_color = ComponentDescriptor(
            ArchetypeName, "BarChart:color", Loggable<rerun::components::Color>::ComponentType
        );
        /// `ComponentDescriptor` for the `abscissa` field.
        static constexpr auto Descriptor_abscissa = ComponentDescriptor(
            ArchetypeName, "BarChart:abscissa",
            Loggable<rerun::components::TensorData>::ComponentType
        );
        /// `ComponentDescriptor` for the `widths` field.
        static constexpr auto Descriptor_widths = ComponentDescriptor(
            ArchetypeName, "BarChart:widths", Loggable<rerun::components::Length>::ComponentType
        );

      public: // START of extensions from bar_chart_ext.cpp:
        BarChart(rerun::datatypes::TensorBuffer buffer) {
            // Forwarding like this can spuriously fail, since the move might be evaluated before `num_elems`:
            //BarChart(rerun::components::TensorData({buffer.num_elems()}, std::move(buffer)));

            auto num_elems = buffer.num_elems();
            *this = std::move(*this).with_values(
                rerun::components::TensorData({num_elems}, std::move(buffer))
            );
        }

        // --------------------------------------------------------------------
        // Implicit constructors:

        /// Construct a `BarChart` from a `Collection<uint8_t>`.
        BarChart(Collection<uint8_t> u8)
            : BarChart(rerun::datatypes::TensorBuffer::u8(std::move(u8))) {}

        /// Construct a `BarChart` from a `Collection<uint16_t>`.
        BarChart(Collection<uint16_t> u16)
            : BarChart(rerun::datatypes::TensorBuffer::u16(std::move(u16))) {}

        /// Construct a `BarChart` from a `Collection<uint32_t>`.
        BarChart(Collection<uint32_t> u32)
            : BarChart(rerun::datatypes::TensorBuffer::u32(std::move(u32))) {}

        /// Construct a `BarChart` from a `Collection<uint64_t>`.
        BarChart(Collection<uint64_t> u64)
            : BarChart(rerun::datatypes::TensorBuffer::u64(std::move(u64))) {}

        /// Construct a `BarChart` from a `Collection<int8_t>`.
        BarChart(Collection<int8_t> i8)
            : BarChart(rerun::datatypes::TensorBuffer::i8(std::move(i8))) {}

        /// Construct a `BarChart` from a `Collection<int16_t>`.
        BarChart(Collection<int16_t> i16)
            : BarChart(rerun::datatypes::TensorBuffer::i16(std::move(i16))) {}

        /// Construct a `BarChart` from a `Collection<int32_t>`.
        BarChart(Collection<int32_t> i32)
            : BarChart(rerun::datatypes::TensorBuffer::i32(std::move(i32))) {}

        /// Construct a `BarChart` from a `Collection<int64_t>`.
        BarChart(Collection<int64_t> i64)
            : BarChart(rerun::datatypes::TensorBuffer::i64(std::move(i64))) {}

        /// Construct aBarChart` from a `Collection<half>`.
        BarChart(Collection<rerun::half> f16)
            : BarChart(rerun::datatypes::TensorBuffer::f16(std::move(f16))) {}

        /// Construct a `BarChart` from a `Collection<float>`.
        BarChart(Collection<float> f32)
            : BarChart(rerun::datatypes::TensorBuffer::f32(std::move(f32))) {}

        /// Construct a `BarChart` from a `Collection<double>`.
        BarChart(Collection<double> f64)
            : BarChart(rerun::datatypes::TensorBuffer::f64(std::move(f64))) {}

        // --------------------------------------------------------------------
        // Explicit static constructors:

        /// Construct a `BarChart` from a `Collection<uint8_t>`.
        static BarChart u8(Collection<uint8_t> u8) {
            return BarChart(std::move(u8));
        }

        /// Construct a `BarChart` from a `Collection<uint16_t>`.
        static BarChart u16(Collection<uint16_t> u16) {
            return BarChart(std::move(u16));
        }

        /// Construct a `BarChart` from a `Collection<uint32_t>`.
        static BarChart u32(Collection<uint32_t> u32) {
            return BarChart(std::move(u32));
        }

        /// Construct a `BarChart` from a `Collection<uint64_t>`.
        static BarChart u64(Collection<uint64_t> u64) {
            return BarChart(std::move(u64));
        }

        /// Construct a `BarChart` from a `Collection<int8_t>`.
        static BarChart i8(Collection<int8_t> i8) {
            return BarChart(std::move(i8));
        }

        /// Construct a `BarChart` from a `Collection<int16_t>`.
        static BarChart i16(Collection<int16_t> i16) {
            return BarChart(std::move(i16));
        }

        /// Construct a `BarChart` from a `Collection<int32_t>`.
        static BarChart i32(Collection<int32_t> i32) {
            return BarChart(std::move(i32));
        }

        /// Construct a `BarChart` from a `Collection<int64_t>`.
        static BarChart i64(Collection<int64_t> i64) {
            return BarChart(std::move(i64));
        }

        /// Construct a `BarChart` from a  `Collection<half>`.
        static BarChart f16(Collection<rerun::half> f16) {
            return BarChart(std::move(f16));
        }

        /// Construct a `BarChart` from a `Collection<float>`.
        static BarChart f32(Collection<float> f32) {
            return BarChart(std::move(f32));
        }

        /// Construct a `BarChart` from a `Collection<double>`.
        static BarChart f64(Collection<double> f64) {
            return BarChart(std::move(f64));
        }

        // END of extensions from bar_chart_ext.cpp, start of generated code:

      public:
        BarChart() = default;
        BarChart(BarChart&& other) = default;
        BarChart(const BarChart& other) = default;
        BarChart& operator=(const BarChart& other) = default;
        BarChart& operator=(BarChart&& other) = default;

        explicit BarChart(rerun::components::TensorData _values)
            : values(ComponentBatch::from_loggable(std::move(_values), Descriptor_values)
                         .value_or_throw()) {}

        /// Update only some specific fields of a `BarChart`.
        static BarChart update_fields() {
            return BarChart();
        }

        /// Clear all the fields of a `BarChart`.
        static BarChart clear_fields();

        /// The values. Should always be a 1-dimensional tensor (i.e. a vector).
        BarChart with_values(const rerun::components::TensorData& _values) && {
            values = ComponentBatch::from_loggable(_values, Descriptor_values).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `values` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_values` should
        /// be used when logging a single row's worth of data.
        BarChart with_many_values(const Collection<rerun::components::TensorData>& _values) && {
            values = ComponentBatch::from_loggable(_values, Descriptor_values).value_or_throw();
            return std::move(*this);
        }

        /// The color of the bar chart
        BarChart with_color(const rerun::components::Color& _color) && {
            color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `color` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_color` should
        /// be used when logging a single row's worth of data.
        BarChart with_many_color(const Collection<rerun::components::Color>& _color) && {
            color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw();
            return std::move(*this);
        }

        /// The abscissa corresponding to each value. Should be a 1-dimensional tensor (i.e. a vector) in same length as values.
        BarChart with_abscissa(const rerun::components::TensorData& _abscissa) && {
            abscissa =
                ComponentBatch::from_loggable(_abscissa, Descriptor_abscissa).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `abscissa` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_abscissa` should
        /// be used when logging a single row's worth of data.
        BarChart with_many_abscissa(const Collection<rerun::components::TensorData>& _abscissa) && {
            abscissa =
                ComponentBatch::from_loggable(_abscissa, Descriptor_abscissa).value_or_throw();
            return std::move(*this);
        }

        /// The width of the bins, defined in x-axis units and defaults to 1. Should be a 1-dimensional tensor (i.e. a vector) in same length as values.
        BarChart with_widths(const Collection<rerun::components::Length>& _widths) && {
            widths = ComponentBatch::from_loggable(_widths, Descriptor_widths).value_or_throw();
            return std::move(*this);
        }

        /// Partitions the component data into multiple sub-batches.
        ///
        /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s
        /// instead, via `ComponentBatch::partitioned`.
        ///
        /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
        ///
        /// The specified `lengths` must sum to the total length of the component batch.
        Collection<ComponentColumn> columns(const Collection<uint32_t>& lengths_);

        /// Partitions the component data into unit-length sub-batches.
        ///
        /// This is semantically similar to calling `columns` with `std::vector<uint32_t>(n, 1)`,
        /// where `n` is automatically guessed.
        Collection<ComponentColumn> columns();
    };

} // namespace rerun::archetypes

namespace rerun {
    /// \private
    template <typename T>
    struct AsComponents;

    /// \private
    template <>
    struct AsComponents<archetypes::BarChart> {
        /// Serialize all set component batches.
        static Result<Collection<ComponentBatch>> as_batches(const archetypes::BarChart& archetype);
    };
} // namespace rerun
