diff --git a/src/lib/eina/Eina.h b/src/lib/eina/Eina.h index bbf3161929..9e3345e432 100644 --- a/src/lib/eina/Eina.h +++ b/src/lib/eina/Eina.h @@ -212,6 +212,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/src/lib/eina/eina_inline_range.x b/src/lib/eina/eina_inline_range.x new file mode 100644 index 0000000000..b5af9d7226 --- /dev/null +++ b/src/lib/eina/eina_inline_range.x @@ -0,0 +1,82 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ +#ifndef EINA_INLINE_RANGE_H_ +#define EINA_INLINE_RANGE_H_ + +/*============================================================================* + * API * + *============================================================================*/ + +static inline size_t eina_range_end(const Eina_Range *range) +{ + if (range) return range->start + range->length; + return 0; +} + +static inline Eina_Range eina_range_intersect(const Eina_Range *range, const Eina_Range *range2) +{ + Eina_Range ret_range = EINA_RANGE_EMPTY(); + size_t min, max; + + if (!range || !range2) + return ret_range; + + min = MAX(range->start, range2->start); + max = MIN(range->start + range->length, range2->start + range2->length); + + if (max > min) + { + ret_range = eina_range_from_to(min, max); + } + + return ret_range; +} + +static inline Eina_Range eina_range_union(const Eina_Range *range, const Eina_Range *range2) +{ + size_t min, max; + + if (!range || !range2) + return EINA_RANGE_EMPTY(); + + min = MIN(range->start, range2->start); + max = MAX(range->start + range->length, range2->start + range2->length); + + return eina_range_from_to(min, max); +} + +static inline Eina_Bool eina_range_contains(const Eina_Range *range, size_t value) +{ + if (!range) return EINA_FALSE; + + return value >= range->start && value < (range->start + range->length); +} + +static inline Eina_Bool eina_range_equal(const Eina_Range *range, const Eina_Range *range2) +{ + if (!range || !range2) return EINA_FALSE; + return (range->start == range2->start && range->length == range2->length); +} + +static inline Eina_Range eina_range_from_to(size_t min, size_t max) +{ + if (min < max) return EINA_RANGE(min, max - min); + return EINA_RANGE(max, min - max);; +} + +#endif // EINA_INLINE_RANGE_H_ \ No newline at end of file diff --git a/src/lib/eina/eina_range.h b/src/lib/eina/eina_range.h new file mode 100644 index 0000000000..b5ffac92f1 --- /dev/null +++ b/src/lib/eina/eina_range.h @@ -0,0 +1,116 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifndef EINA_RANGE_H_ +#define EINA_RANGE_H_ + +#include "eina_types.h" + +#include "eina_cpu.h" + +#define EINA_RANGE(start, length) ((Eina_Range) { (start), (length) }) +#define EINA_RANGE_FROM_TO(from, to) ((Eina_Range) { MIN((from),(to)), ABS((to) - (from)) }) +#define EINA_RANGE_ZERO() EINA_RANGE(0, 0) +#define EINA_RANGE_EMPTY() ((Eina_Range) EINA_RANGE_ZERO()) + +/** @brief A Int range */ +typedef struct _Eina_Range +{ + size_t start; + size_t length; +} Eina_Range; + + +/** + * @brief convenience macro for comparing two Eina_Range structs + * @param[in] a An Eina_Range + * @param[in] b An Eina_Range + * @return 1 if the structs are equal, 0 if they are not + * @since 1.24 + */ +#define EINA_RANGE_EQ(a, b) \ + (((a).start == (b).start) && ((a).length == (b).length)) + +/** + * @brief Get end value in range (not included in range). + * + * @param[in] range The Range. + * @return The sum of end and length of the range. + * + * @since 1.24 + * */ +static inline size_t eina_range_end(const Eina_Range *range); + +/** + * @brief Intersection between two ranges. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return The intersection between two ranges, If ranges do not intersect return length will be 0. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_intersect(const Eina_Range *range, const Eina_Range *range2); + + +/** + * @brief Union between two ranges. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return The union between two ranges. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_union(const Eina_Range *range, const Eina_Range *range2); + +/** + * @brief Check if value is set in a range. + * + * @param[in] range The range. + * @return Wither value set within range. + * + * @since 1.24 + * */ +static inline Eina_Bool eina_range_contains(const Eina_Range *range, size_t value); + +/** + * @brief Check if two ranges are equal. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return Wither two ranges are equal. + * + * @since 1.24 + * */ +static inline Eina_Bool eina_range_equal(const Eina_Range *range, const Eina_Range *range2); + +/** + * @brief Check if two ranges are equal. + * + * @param[in] min The min value in range. + * @param[in] max The max value in range. + * @return range. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_from_to(size_t min, size_t max); + +#include "eina_inline_range.x" + +#endif /*EINA_RANGE_H_*/ diff --git a/src/lib/eina/meson.build b/src/lib/eina/meson.build index 7866323742..97e1669c4f 100644 --- a/src/lib/eina/meson.build +++ b/src/lib/eina/meson.build @@ -32,6 +32,7 @@ public_sub_headers = [ 'eina_mempool.h', 'eina_module.h', 'eina_rectangle.h', +'eina_range.h', 'eina_types.h', 'eina_array.h', 'eina_counter.h', @@ -51,6 +52,7 @@ public_sub_headers = [ 'eina_inline_rbtree.x', 'eina_inline_mempool.x', 'eina_inline_rectangle.x', +'eina_inline_range.x', 'eina_inline_trash.x', 'eina_thread.h', 'eina_trash.h', diff --git a/src/lib/eo/eina_types.eot b/src/lib/eo/eina_types.eot index 4cb8e9347d..d4033e26aa 100644 --- a/src/lib/eo/eina_types.eot +++ b/src/lib/eo/eina_types.eot @@ -60,6 +60,12 @@ struct @extern Eina.Matrix3 { zz: double; [[ZZ matrix value]] } +struct @extern @beta Eina.Range { + [[A range sequence of values.]] + start: size; [[Start of the range.]] + length: size; [[Length of the range.]] +} + type @extern Eina.Unicode: uint32; [[Eina unicode type. @since 1.24]] struct @extern @beta Eina.File_Direct_Info; [[Eina file direct information data structure]] diff --git a/src/tests/eina/eina_suite.c b/src/tests/eina/eina_suite.c index dfa2bd1e5f..45316bd462 100644 --- a/src/tests/eina/eina_suite.c +++ b/src/tests/eina/eina_suite.c @@ -57,6 +57,7 @@ static const Efl_Test_Case etc[] = { { "Benchmark", eina_test_benchmark }, { "Mempool", eina_test_mempool }, { "Rectangle", eina_test_rectangle }, + { "Range", eina_test_range }, { "MatrixSparse", eina_test_matrixsparse }, { "Tiler", eina_test_tiler }, { "Strbuf", eina_test_strbuf }, diff --git a/src/tests/eina/eina_suite.h b/src/tests/eina/eina_suite.h index 5e7a1bf30f..102de63193 100644 --- a/src/tests/eina/eina_suite.h +++ b/src/tests/eina/eina_suite.h @@ -45,6 +45,7 @@ void eina_test_file(TCase *tc); void eina_test_benchmark(TCase *tc); void eina_test_mempool(TCase *tc); void eina_test_rectangle(TCase *tc); +void eina_test_range(TCase *tc); void eina_test_matrixsparse(TCase *tc); void eina_test_tiler(TCase *tc); void eina_test_strbuf(TCase *tc); diff --git a/src/tests/eina/eina_test_range.c b/src/tests/eina/eina_test_range.c new file mode 100644 index 0000000000..a1f84b8a00 --- /dev/null +++ b/src/tests/eina/eina_test_range.c @@ -0,0 +1,72 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#include "eina_suite.h" + +EFL_START_TEST(eina_range_intersect_union_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + Eina_Range r2 = EINA_RANGE(5, 15); + + Eina_Range r_intersect = eina_range_intersect(&r1, &r2); + ck_assert_uint_eq(r_intersect.start, 5); + ck_assert_uint_eq(r_intersect.length, 5); + + Eina_Range r_union = eina_range_union(&r1, &r2); + ck_assert_uint_eq(r_union.start, 0); + ck_assert_uint_eq(r_union.length, 20); +} +EFL_END_TEST + +EFL_START_TEST(eina_range_contains_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + + ck_assert(eina_range_contains(&r1,0)); + ck_assert(eina_range_contains(&r1,9)); + ck_assert(!eina_range_contains(&r1,10)); +} +EFL_END_TEST + +EFL_START_TEST(eina_range_equal_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + Eina_Range r2 = EINA_RANGE(0, 10); + Eina_Range r3 = EINA_RANGE(0, 9); + + ck_assert(eina_range_equal(&r1, &r2)); + ck_assert(!eina_range_equal(&r1, &r3)); +} +EFL_END_TEST + + +void +eina_test_range(TCase *tc) +{ + tcase_add_test(tc, eina_range_intersect_union_test); + tcase_add_test(tc, eina_range_contains_test); + tcase_add_test(tc, eina_range_equal_test); +} diff --git a/src/tests/eina/meson.build b/src/tests/eina/meson.build index b6ba688e8b..f755be4c2a 100644 --- a/src/tests/eina/meson.build +++ b/src/tests/eina/meson.build @@ -29,6 +29,7 @@ eina_test_src = files( 'eina_test_benchmark.c', 'eina_test_mempool.c', 'eina_test_rectangle.c', +'eina_test_range.c', 'eina_test_list.c', 'eina_test_matrixsparse.c', 'eina_test_tiler.c',