summaryrefslogtreecommitdiffstats
path: root/src/arrow/c_glib/arrow-glib/decimal.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/arrow/c_glib/arrow-glib/decimal.cpp
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/arrow/c_glib/arrow-glib/decimal.cpp')
-rw-r--r--src/arrow/c_glib/arrow-glib/decimal.cpp1115
1 files changed, 1115 insertions, 0 deletions
diff --git a/src/arrow/c_glib/arrow-glib/decimal.cpp b/src/arrow/c_glib/arrow-glib/decimal.cpp
new file mode 100644
index 000000000..497d76fcf
--- /dev/null
+++ b/src/arrow/c_glib/arrow-glib/decimal.cpp
@@ -0,0 +1,1115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <arrow-glib/decimal.hpp>
+#include <arrow-glib/error.hpp>
+
+template <typename Decimal>
+struct DecimalConverter {
+};
+
+template <>
+struct DecimalConverter<arrow::Decimal128> {
+ using ArrowType = arrow::Decimal128;
+ using GArrowType = GArrowDecimal128;
+
+ GArrowType *
+ new_raw(std::shared_ptr<ArrowType> *arrow_decimal128)
+ {
+ return garrow_decimal128_new_raw(arrow_decimal128);
+ }
+
+ std::shared_ptr<ArrowType>
+ get_raw(GArrowType *decimal128)
+ {
+ return garrow_decimal128_get_raw(decimal128);
+ }
+};
+
+template <>
+struct DecimalConverter<arrow::Decimal256> {
+ using ArrowType = arrow::Decimal256;
+ using GArrowType = GArrowDecimal256;
+
+ GArrowType *
+ new_raw(std::shared_ptr<ArrowType> *arrow_decimal256) {
+ return garrow_decimal256_new_raw(arrow_decimal256);
+ }
+
+ std::shared_ptr<ArrowType>
+ get_raw(GArrowType *decimal256) {
+ return garrow_decimal256_get_raw(decimal256);
+ }
+};
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_new_string(const gchar *data)
+{
+ auto arrow_decimal = std::make_shared<Decimal>(data);
+ DecimalConverter<Decimal> converter;
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_new_integer(const gint64 data)
+{
+ auto arrow_decimal = std::make_shared<Decimal>(data);
+ DecimalConverter<Decimal> converter;
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_copy(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ auto arrow_copied_decimal = std::make_shared<Decimal>(*arrow_decimal);
+ return converter.new_raw(&arrow_copied_decimal);
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal == *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_not_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal != *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_less_than(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal < *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_less_than_or_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal <= *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_greater_than(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal > *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_greater_than_or_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal >= *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gchar *
+garrow_decimal_to_string_scale(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ gint32 scale)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ return g_strdup(arrow_decimal->ToString(scale).c_str());
+}
+
+template <typename Decimal>
+gchar *
+garrow_decimal_to_string(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ return g_strdup(arrow_decimal->ToIntegerString().c_str());
+}
+
+template <typename Decimal>
+GBytes *
+garrow_decimal_to_bytes(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ uint8_t data[DecimalConverter<Decimal>::ArrowType::kBitWidth / 8];
+ arrow_decimal->ToBytes(data);
+ return g_bytes_new(data, sizeof(data));
+}
+
+template <typename Decimal>
+void
+garrow_decimal_abs(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ arrow_decimal->Abs();
+}
+
+template <typename Decimal>
+void
+garrow_decimal_negate(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ arrow_decimal->Negate();
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_plus(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left + *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_minus(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left - *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_multiply(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left * *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_divide(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right,
+ typename DecimalConverter<Decimal>::GArrowType **remainder,
+ GError **error,
+ const gchar *tag)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_result = arrow_left->Divide(*arrow_right);
+ if (garrow::check(error, arrow_result, tag)) {
+ Decimal arrow_quotient_raw;
+ Decimal arrow_remainder_raw;
+ std::tie(arrow_quotient_raw, arrow_remainder_raw) = *arrow_result;
+ if (remainder) {
+ auto arrow_remainder = std::make_shared<Decimal>(arrow_remainder_raw);
+ *remainder = converter.new_raw(&arrow_remainder);
+ }
+ auto arrow_quotient = std::make_shared<Decimal>(arrow_quotient_raw);
+ return converter.new_raw(&arrow_quotient);
+ } else {
+ if (remainder) {
+ *remainder = NULL;
+ }
+ return NULL;
+ }
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_rescale(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error,
+ const gchar *tag)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ auto arrow_result = arrow_decimal->Rescale(original_scale, new_scale);
+ if (garrow::check(error, arrow_result, tag)) {
+ auto arrow_rescaled_decimal = std::make_shared<Decimal>(*arrow_result);
+ return converter.new_raw(&arrow_rescaled_decimal);
+ } else {
+ return NULL;
+ }
+}
+
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: decimal
+ * @section_id: decimal
+ * @title: 128-bit and 256-bit decimal classes
+ * @include: arrow-glib/arrow-glib.h
+ *
+ * #GArrowDecimal128 is a 128-bit decimal class.
+ *
+ * #GArrowDecimal256 is a 256-bit decimal class.
+ *
+ * Since: 0.10.0
+ */
+
+typedef struct GArrowDecimal128Private_ {
+ std::shared_ptr<arrow::Decimal128> decimal128;
+} GArrowDecimal128Private;
+
+enum {
+ PROP_DECIMAL128 = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal128,
+ garrow_decimal128,
+ G_TYPE_OBJECT)
+
+#define GARROW_DECIMAL128_GET_PRIVATE(obj) \
+ static_cast<GArrowDecimal128Private *>( \
+ garrow_decimal128_get_instance_private( \
+ GARROW_DECIMAL128(obj)))
+
+static void
+garrow_decimal128_finalize(GObject *object)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+
+ priv->decimal128.~shared_ptr();
+
+ G_OBJECT_CLASS(garrow_decimal128_parent_class)->finalize(object);
+}
+
+static void
+garrow_decimal128_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_DECIMAL128:
+ priv->decimal128 =
+ *static_cast<std::shared_ptr<arrow::Decimal128> *>(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_decimal128_init(GArrowDecimal128 *object)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+ new(&priv->decimal128) std::shared_ptr<arrow::Decimal128>;
+}
+
+static void
+garrow_decimal128_class_init(GArrowDecimal128Class *klass)
+{
+ GParamSpec *spec;
+
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->finalize = garrow_decimal128_finalize;
+ gobject_class->set_property = garrow_decimal128_set_property;
+
+ spec = g_param_spec_pointer("decimal128",
+ "Decimal128",
+ "The raw std::shared<arrow::Decimal128> *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_DECIMAL128, spec);
+}
+
+/**
+ * garrow_decimal128_new_string:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal128.
+ *
+ * Since: 0.10.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_new_string(const gchar *data)
+{
+ return garrow_decimal_new_string<arrow::Decimal128>(data);
+}
+
+/**
+ * garrow_decimal128_new_integer:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal128.
+ *
+ * Since: 0.10.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_new_integer(const gint64 data)
+{
+ return garrow_decimal_new_integer<arrow::Decimal128>(data);
+}
+
+/**
+ * garrow_decimal128_copy:
+ * @decimal: The decimal to be copied.
+ *
+ * Returns: (transfer full): A copied #GArrowDecimal128.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_copy(GArrowDecimal128 *decimal)
+{
+ return garrow_decimal_copy<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
+ * otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_not_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal isn't equal to the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_not_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_not_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_less_than:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_less_than(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_less_than<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_less_than_or_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_less_than_or_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_less_than_or_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_greater_than:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_greater_than(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_greater_than<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_greater_than_or_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_greater_than_or_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_greater_than_or_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_to_string_scale:
+ * @decimal: A #GArrowDecimal128.
+ * @scale: The scale of the decimal.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 0.10.0
+ */
+gchar *
+garrow_decimal128_to_string_scale(GArrowDecimal128 *decimal, gint32 scale)
+{
+ return garrow_decimal_to_string_scale<arrow::Decimal128>(decimal, scale);
+}
+
+/**
+ * garrow_decimal128_to_string:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 0.10.0
+ */
+gchar *
+garrow_decimal128_to_string(GArrowDecimal128 *decimal)
+{
+ return garrow_decimal_to_string<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_to_bytes:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The binary representation of the decimal.
+ *
+ * Since: 3.0.0
+ */
+GBytes *
+garrow_decimal128_to_bytes(GArrowDecimal128 *decimal)
+{
+ return garrow_decimal_to_bytes<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_abs:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Computes the absolute value of the @decimal destructively.
+ *
+ * Since: 0.10.0
+ */
+void
+garrow_decimal128_abs(GArrowDecimal128 *decimal)
+{
+ garrow_decimal_abs<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_negate:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Negate the current value of the @decimal destructively.
+ *
+ * Since: 0.10.0
+ */
+void
+garrow_decimal128_negate(GArrowDecimal128 *decimal)
+{
+ garrow_decimal_negate<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_to_integer:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Returns: The 64-bit integer representation of the decimal.
+ *
+ * Since: 0.10.0
+ */
+gint64
+garrow_decimal128_to_integer(GArrowDecimal128 *decimal)
+{
+ auto arrow_decimal = garrow_decimal128_get_raw(decimal);
+ return static_cast<int64_t>(*arrow_decimal);
+}
+
+/**
+ * garrow_decimal128_plus:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The added value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_plus(GArrowDecimal128 *left,
+ GArrowDecimal128 *right)
+{
+ return garrow_decimal_plus<arrow::Decimal128>(left, right);
+}
+
+/**
+ * garrow_decimal128_minus:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The subtracted value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_minus(GArrowDecimal128 *left,
+ GArrowDecimal128 *right)
+{
+ return garrow_decimal_minus<arrow::Decimal128>(left, right);
+}
+
+/**
+ * garrow_decimal128_multiply:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The multiplied value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_multiply(GArrowDecimal128 *left,
+ GArrowDecimal128 *right)
+{
+ return garrow_decimal_multiply<arrow::Decimal128>(left, right);
+}
+
+/**
+ * garrow_decimal128_divide:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ * @remainder: (out) (nullable): A return location for the remainder
+ * value of these decimals. The returned #GArrowDecimal128 be
+ * unreferred with g_object_unref() when no longer needed.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The divided value of
+ * these decimals or %NULL on error.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_divide(GArrowDecimal128 *left,
+ GArrowDecimal128 *right,
+ GArrowDecimal128 **remainder,
+ GError **error)
+{
+ return garrow_decimal_divide<arrow::Decimal128>(left,
+ right,
+ remainder,
+ error,
+ "[decimal128][divide]");
+}
+
+/**
+ * garrow_decimal128_rescale:
+ * @decimal: A #GArrowDecimal128.
+ * @original_scale: A scale to be converted from.
+ * @new_scale: A scale to be converted to.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The rescaled decimal or %NULL on error.
+ *
+ * Since: 0.15.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_rescale(GArrowDecimal128 *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error)
+{
+ return garrow_decimal_rescale<arrow::Decimal128>(decimal,
+ original_scale,
+ new_scale,
+ error,
+ "[decimal128][rescale]");
+}
+
+
+typedef struct GArrowDecimal256Private_ {
+ std::shared_ptr<arrow::Decimal256> decimal256;
+} GArrowDecimal256Private;
+
+enum {
+ PROP_DECIMAL256 = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal256,
+ garrow_decimal256,
+ G_TYPE_OBJECT)
+
+#define GARROW_DECIMAL256_GET_PRIVATE(obj) \
+ static_cast<GArrowDecimal256Private *>( \
+ garrow_decimal256_get_instance_private( \
+ GARROW_DECIMAL256(obj)))
+
+static void
+garrow_decimal256_finalize(GObject *object)
+{
+ auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
+
+ priv->decimal256.~shared_ptr();
+
+ G_OBJECT_CLASS(garrow_decimal256_parent_class)->finalize(object);
+}
+
+static void
+garrow_decimal256_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_DECIMAL256:
+ priv->decimal256 =
+ *static_cast<std::shared_ptr<arrow::Decimal256> *>(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_decimal256_init(GArrowDecimal256 *object)
+{
+ auto priv = GARROW_DECIMAL256_GET_PRIVATE(object);
+ new(&priv->decimal256) std::shared_ptr<arrow::Decimal256>;
+}
+
+static void
+garrow_decimal256_class_init(GArrowDecimal256Class *klass)
+{
+ GParamSpec *spec;
+
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->finalize = garrow_decimal256_finalize;
+ gobject_class->set_property = garrow_decimal256_set_property;
+
+ spec = g_param_spec_pointer("decimal256",
+ "Decimal256",
+ "The raw std::shared<arrow::Decimal256> *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_DECIMAL256, spec);
+}
+
+/**
+ * garrow_decimal256_new_string:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal256.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_new_string(const gchar *data)
+{
+ return garrow_decimal_new_string<arrow::Decimal256>(data);
+}
+
+/**
+ * garrow_decimal256_new_integer:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal256.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_new_integer(const gint64 data)
+{
+ return garrow_decimal_new_integer<arrow::Decimal256>(data);
+}
+
+/**
+ * garrow_decimal256_copy:
+ * @decimal: The decimal to be copied.
+ *
+ * Returns: (transfer full): A copied #GArrowDecimal256.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_copy(GArrowDecimal256 *decimal)
+{
+ return garrow_decimal_copy<arrow::Decimal256>(decimal);
+}
+
+/**
+ * garrow_decimal256_equal:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
+ * otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_equal(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_equal<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_not_equal:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal isn't equal to the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_not_equal(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_not_equal<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_less_than:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_less_than(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_less_than<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_less_than_or_equal:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_less_than_or_equal(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_less_than_or_equal<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_greater_than:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_greater_than(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_greater_than<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_greater_than_or_equal:
+ * @decimal: A #GArrowDecimal256.
+ * @other_decimal: A #GArrowDecimal256 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_decimal256_greater_than_or_equal(GArrowDecimal256 *decimal,
+ GArrowDecimal256 *other_decimal)
+{
+ return garrow_decimal_greater_than_or_equal<arrow::Decimal256>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal256_to_string_scale:
+ * @decimal: A #GArrowDecimal256.
+ * @scale: The scale of the decimal.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 3.0.0
+ */
+gchar *
+garrow_decimal256_to_string_scale(GArrowDecimal256 *decimal, gint32 scale)
+{
+ return garrow_decimal_to_string_scale<arrow::Decimal256>(decimal, scale);
+}
+
+/**
+ * garrow_decimal256_to_string:
+ * @decimal: A #GArrowDecimal256.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 3.0.0
+ */
+gchar *
+garrow_decimal256_to_string(GArrowDecimal256 *decimal)
+{
+ return garrow_decimal_to_string<arrow::Decimal256>(decimal);
+}
+
+/**
+ * garrow_decimal256_to_bytes:
+ * @decimal: A #GArrowDecimal256.
+ *
+ * Returns: (transfer full): The binary representation of the decimal.
+ *
+ * Since: 3.0.0
+ */
+GBytes *
+garrow_decimal256_to_bytes(GArrowDecimal256 *decimal)
+{
+ return garrow_decimal_to_bytes<arrow::Decimal256>(decimal);
+}
+
+/**
+ * garrow_decimal256_abs:
+ * @decimal: A #GArrowDecimal256.
+ *
+ * Computes the absolute value of the @decimal destructively.
+ *
+ * Since: 3.0.0
+ */
+void
+garrow_decimal256_abs(GArrowDecimal256 *decimal)
+{
+ garrow_decimal_abs<arrow::Decimal256>(decimal);
+}
+
+/**
+ * garrow_decimal256_negate:
+ * @decimal: A #GArrowDecimal256.
+ *
+ * Negate the current value of the @decimal destructively.
+ *
+ * Since: 3.0.0
+ */
+void
+garrow_decimal256_negate(GArrowDecimal256 *decimal)
+{
+ garrow_decimal_negate<arrow::Decimal256>(decimal);
+}
+
+/**
+ * garrow_decimal256_plus:
+ * @left: A #GArrowDecimal256.
+ * @right: A #GArrowDecimal256.
+ *
+ * Returns: (transfer full): The added value of these decimals.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_plus(GArrowDecimal256 *left,
+ GArrowDecimal256 *right)
+{
+ return garrow_decimal_plus<arrow::Decimal256>(left, right);
+}
+
+/**
+ * garrow_decimal256_multiply:
+ * @left: A #GArrowDecimal256.
+ * @right: A #GArrowDecimal256.
+ *
+ * Returns: (transfer full): The multiplied value of these decimals.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_multiply(GArrowDecimal256 *left,
+ GArrowDecimal256 *right)
+{
+ return garrow_decimal_multiply<arrow::Decimal256>(left, right);
+}
+
+/**
+ * garrow_decimal256_divide:
+ * @left: A #GArrowDecimal256.
+ * @right: A #GArrowDecimal256.
+ * @remainder: (out) (nullable): A return location for the remainder
+ * value of these decimals. The returned #GArrowDecimal256 be
+ * unreferred with g_object_unref() when no longer needed.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The divided value of
+ * these decimals or %NULL on error.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_divide(GArrowDecimal256 *left,
+ GArrowDecimal256 *right,
+ GArrowDecimal256 **remainder,
+ GError **error)
+{
+ return garrow_decimal_divide<arrow::Decimal256>(left,
+ right,
+ remainder,
+ error,
+ "[decimal256][divide]");
+}
+
+/**
+ * garrow_decimal256_rescale:
+ * @decimal: A #GArrowDecimal256.
+ * @original_scale: A scale to be converted from.
+ * @new_scale: A scale to be converted to.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The rescaled decimal or %NULL on error.
+ *
+ * Since: 3.0.0
+ */
+GArrowDecimal256 *
+garrow_decimal256_rescale(GArrowDecimal256 *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error)
+{
+ return garrow_decimal_rescale<arrow::Decimal256>(decimal,
+ original_scale,
+ new_scale,
+ error,
+ "[decimal256][rescale]");
+}
+
+
+G_END_DECLS
+
+GArrowDecimal128 *
+garrow_decimal128_new_raw(std::shared_ptr<arrow::Decimal128> *arrow_decimal128)
+{
+ auto decimal128 = g_object_new(garrow_decimal128_get_type(),
+ "decimal128", arrow_decimal128,
+ NULL);
+ return GARROW_DECIMAL128(decimal128);
+}
+
+std::shared_ptr<arrow::Decimal128>
+garrow_decimal128_get_raw(GArrowDecimal128 *decimal128)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(decimal128);
+ return priv->decimal128;
+}
+
+GArrowDecimal256 *
+garrow_decimal256_new_raw(std::shared_ptr<arrow::Decimal256> *arrow_decimal256)
+{
+ auto decimal256 = g_object_new(garrow_decimal256_get_type(),
+ "decimal256", arrow_decimal256,
+ NULL);
+ return GARROW_DECIMAL256(decimal256);
+}
+
+std::shared_ptr<arrow::Decimal256>
+garrow_decimal256_get_raw(GArrowDecimal256 *decimal256)
+{
+ auto priv = GARROW_DECIMAL256_GET_PRIVATE(decimal256);
+ return priv->decimal256;
+}