eina: add new range Data type

Summary:
Introduce new data type (Eina.Range)  which represent range (part of series)

**eina_range_max_get**
**eina_range_intersect**
**eina_range_union**
**eina_range_contains**
**eina_range_equal**

Reviewers: cedric, woohyun, bu5hm4n, segfaultxavi, zmike

Reviewed By: woohyun

Subscribers: vtorri, cedric, #committers, #reviewers

Tags: #efl

Maniphest Tasks: T8570

Differential Revision: https://phab.enlightenment.org/D11133
This commit is contained in:
Ali Alzyod 2020-01-23 06:54:44 +09:00 committed by WooHyun Jung
parent 93bd970259
commit 5137f6d143
9 changed files with 282 additions and 0 deletions

View File

@ -212,6 +212,7 @@ extern "C" {
#include <eina_main.h>
#include <eina_fp.h>
#include <eina_rectangle.h>
#include <eina_range.h>
#include <eina_clist.h>
#include <eina_inlist.h>
#include <eina_file.h>

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_

116
src/lib/eina/eina_range.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_*/

View File

@ -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',

View File

@ -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]]

View File

@ -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 },

View File

@ -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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <Eina.h>
#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);
}

View File

@ -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',