efl/src/lib/eina/eina_matrixsparse.c

1410 lines
36 KiB
C
Raw Normal View History

/* EINA - EFL data type library
* Copyright (C) 2009 Gustavo Sverzut Barbieri
*
* 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/>.
*/
/**
2009-12-25 08:22:13 -08:00
* @page tutorial_matrixsparse_page Sparse Matrix Tutorial
*
* to be written...
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "eina_config.h"
#include "eina_private.h"
#include "eina_log.h"
#include "eina_magic.h"
#include "eina_mempool.h"
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
#include "eina_safety_checks.h"
#include "eina_matrixsparse.h"
/*============================================================================*
2010-07-27 19:37:05 -07:00
* Local *
*============================================================================*/
2009-12-25 08:22:13 -08:00
/**
* @cond LOCAL
*/
static const char EINA_MAGIC_MATRIXSPARSE_STR[] = "Eina Matrixsparse";
static const char EINA_MAGIC_MATRIXSPARSE_ROW_STR[] = "Eina Matrixsparse Row";
static const char EINA_MAGIC_MATRIXSPARSE_CELL_STR[] = "Eina Matrixsparse Cell";
2010-07-27 19:37:05 -07:00
static const char EINA_MAGIC_MATRIXSPARSE_ITERATOR_STR[] =
"Eina Matrixsparse Iterator";
static const char EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR_STR[] =
"Eina Matrixsparse Row Accessor";
static const char EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR_STR[] =
"Eina Matrixsparse Row Iterator";
static const char EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR_STR[] =
"Eina Matrixsparse Cell Accessor";
static const char EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR_STR[] =
"Eina Matrixsparse Cell Iterator";
#define EINA_MAGIC_CHECK_MATRIXSPARSE(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE)) \
{ \
EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE); \
return __VA_ARGS__; \
} \
} while(0)
#define EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ROW)) \
{ \
EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ROW); \
return __VA_ARGS__; \
} \
} while(0)
#define EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_CELL)) \
{ \
EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_CELL); \
return __VA_ARGS__; \
} \
} while(0)
#define EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR)) \
{ \
EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR); \
return __VA_ARGS__; \
} \
} while(0)
struct _Eina_Matrixsparse_Cell
{
Eina_Matrixsparse_Cell *next;
Eina_Matrixsparse_Cell *prev;
void *data;
unsigned long col;
Eina_Matrixsparse_Row *parent;
EINA_MAGIC
};
struct _Eina_Matrixsparse_Row
{
Eina_Matrixsparse_Row *next;
Eina_Matrixsparse_Row *prev;
Eina_Matrixsparse_Cell *cols;
Eina_Matrixsparse_Cell *last_col;
Eina_Matrixsparse_Cell *last_used; /* fast sequential access */
unsigned long row;
Eina_Matrixsparse *parent;
EINA_MAGIC
};
struct _Eina_Matrixsparse
{
Eina_Matrixsparse_Row *rows;
Eina_Matrixsparse_Row *last_row;
Eina_Matrixsparse_Row *last_used; /* fast sequential access */
struct
{
unsigned long rows;
unsigned long cols;
} size;
struct
{
void (*func)(void *user_data, void *cell_data);
void *user_data;
} free;
EINA_MAGIC
};
typedef struct _Eina_Matrixsparse_Iterator Eina_Matrixsparse_Iterator;
2010-07-27 19:37:05 -07:00
typedef struct _Eina_Matrixsparse_Iterator_Complete
Eina_Matrixsparse_Iterator_Complete;
struct _Eina_Matrixsparse_Iterator
{
Eina_Iterator iterator;
const Eina_Matrixsparse *m;
2010-07-27 19:37:05 -07:00
struct
{
const Eina_Matrixsparse_Row *row;
const Eina_Matrixsparse_Cell *col;
} ref;
EINA_MAGIC
};
struct _Eina_Matrixsparse_Iterator_Complete
{
Eina_Iterator iterator;
const Eina_Matrixsparse *m;
2010-07-27 19:37:05 -07:00
struct
{
const Eina_Matrixsparse_Row *row;
const Eina_Matrixsparse_Cell *col;
} ref;
2010-07-27 19:37:05 -07:00
struct
{
unsigned long row, col;
} idx;
2010-07-27 19:37:05 -07:00
struct
{
Eina_Matrixsparse_Row row;
Eina_Matrixsparse_Cell col;
} dummy;
EINA_MAGIC
};
/**
* @todo Eina_Matrixsparse_Row_Iterator: iterator over rows in matrix
* @todo Eina_Matrixsparse_Row_Accessor: accessor over rows in matrix
* @todo Eina_Matrixsparse_Cell_Iterator: iterator over cells in row
* @todo Eina_Matrixsparse_Cell_Accessor: accessor over cells in row
*/
static int _eina_matrixsparse_log_dom = -1;
#ifdef ERR
#undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_eina_matrixsparse_log_dom, __VA_ARGS__)
#ifdef DBG
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eina_matrixsparse_log_dom, __VA_ARGS__)
static Eina_Mempool *_eina_matrixsparse_cell_mp = NULL;
static Eina_Mempool *_eina_matrixsparse_row_mp = NULL;
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_cell_free(Eina_Matrixsparse_Cell *c, void (*free_func)(
void *,
void *), void *user_data)
{
if (free_func)
2010-07-27 19:37:05 -07:00
free_func(user_data, c->data);
EINA_MAGIC_SET(c, EINA_MAGIC_NONE);
eina_mempool_free(_eina_matrixsparse_cell_mp, c);
}
static inline void
_eina_matrixsparse_cell_unlink(Eina_Matrixsparse_Cell *c)
{
Eina_Matrixsparse_Row *r = c->parent;
if (r->last_used == c)
{
2010-07-27 19:37:05 -07:00
if (c->next)
r->last_used = c->next;
else
r->last_used = c->prev;
}
if (r->last_col == c)
2010-07-27 19:37:05 -07:00
r->last_col = c->prev;
if (r->cols == c)
2010-07-27 19:37:05 -07:00
r->cols = c->next;
if (c->next && c->prev)
{
2010-07-27 19:37:05 -07:00
c->next->prev = c->prev;
c->prev->next = c->next;
}
else if (c->next)
2010-07-27 19:37:05 -07:00
c->next->prev = NULL;
else if (c->prev)
2010-07-27 19:37:05 -07:00
c->prev->next = NULL;
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_cells_free(Eina_Matrixsparse_Row *r, void (*free_func)(
void *,
void *), void *user_data)
{
Eina_Matrixsparse_Cell *c = r->cols;
while (c)
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Cell *c_aux = c;
c = c->next;
_eina_matrixsparse_cell_free(c_aux, free_func, user_data);
}
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_free(Eina_Matrixsparse_Row *r, void (*free_func)(void *,
void *),
void *user_data)
{
_eina_matrixsparse_row_cells_free(r, free_func, user_data);
EINA_MAGIC_SET(r, EINA_MAGIC_NONE);
eina_mempool_free(_eina_matrixsparse_row_mp, r);
}
static inline void
_eina_matrixsparse_row_unlink(Eina_Matrixsparse_Row *r)
{
Eina_Matrixsparse *m = r->parent;
if (m->last_used == r)
{
2010-07-27 19:37:05 -07:00
if (r->next)
m->last_used = r->next;
else
m->last_used = r->prev;
}
if (m->last_row == r)
2010-07-27 19:37:05 -07:00
m->last_row = r->prev;
if (m->rows == r)
2010-07-27 19:37:05 -07:00
m->rows = r->next;
if (r->next && r->prev)
{
2010-07-27 19:37:05 -07:00
r->next->prev = r->prev;
r->prev->next = r->next;
}
else if (r->next)
2010-07-27 19:37:05 -07:00
r->next->prev = NULL;
else if (r->prev)
2010-07-27 19:37:05 -07:00
r->prev->next = NULL;
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_find_parms_get(const Eina_Matrixsparse *m,
unsigned long row,
Eina_Matrixsparse_Row **p_r,
int *p_dir)
{
Eina_Matrixsparse_Row *r;
unsigned long dist;
int dir;
dist = row - m->rows->row;
r = m->rows;
dir = 1;
if (dist > m->last_row->row - row)
{
2010-07-27 19:37:05 -07:00
dist = m->last_row->row - row;
r = m->last_row;
dir = -1;
}
if (m->last_used)
{
2010-07-27 19:37:05 -07:00
if (m->last_used->row < row)
{
if (dist > row - m->last_used->row)
{
/* dist = row = m->last_used->row; */
r = m->last_used;
dir = 1;
}
}
else if (dist > m->last_used->row - row)
{
/* dist = m->last_used->row - row; */
r = m->last_used;
dir = -1;
}
}
*p_r = r;
*p_dir = dir;
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_cell_find_parms_get(const Eina_Matrixsparse_Row *r,
unsigned long col,
Eina_Matrixsparse_Cell **p_c,
int *p_dir)
{
Eina_Matrixsparse_Cell *c;
unsigned long dist;
int dir;
dist = col - r->cols->col;
c = r->cols;
dir = 1;
if (dist > r->last_col->col - col)
{
2010-07-27 19:37:05 -07:00
dist = r->last_col->col - col;
c = r->last_col;
dir = -1;
}
if (r->last_used)
{
2010-07-27 19:37:05 -07:00
if (r->last_used->col < col)
{
if (dist > col - r->last_used->col)
{
/* dist = col = r->last_used->col; */
c = r->last_used;
dir = 1;
}
}
else if (dist > r->last_used->col - col)
{
/* dist = r->last_used->col - col; */
c = r->last_used;
dir = -1;
}
}
*p_c = c;
*p_dir = dir;
}
static inline Eina_Matrixsparse_Row *
_eina_matrixsparse_row_idx_get(const Eina_Matrixsparse *m, unsigned long row)
{
Eina_Matrixsparse_Row *r;
int dir;
2010-07-27 19:37:05 -07:00
if (!m->rows)
return NULL;
2010-07-27 19:37:05 -07:00
if (m->rows->row == row)
return m->rows;
else if (m->rows->row > row)
return NULL;
2010-07-27 19:37:05 -07:00
if (m->last_row->row == row)
return m->last_row;
else if (m->last_row->row < row)
return NULL;
2010-07-27 19:37:05 -07:00
if ((m->last_used) && (m->last_used->row == row))
return m->last_used;
_eina_matrixsparse_row_find_parms_get(m, row, &r, &dir);
assert(dir != 0);
if (dir > 0)
{
for (; r; r = r->next)
2010-07-27 19:37:05 -07:00
if (r->row == row)
{
((Eina_Matrixsparse *)m)->last_used = r;
return r;
}
else if (r->row > row)
return NULL;
}
else if (dir < 0)
{
for (; r; r = r->prev)
if (r->row == row)
{
((Eina_Matrixsparse *)m)->last_used = r;
return r;
}
else if (r->row < row)
2010-07-27 19:37:05 -07:00
return NULL;
}
return NULL;
}
static inline Eina_Matrixsparse_Cell *
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_cell_idx_get(const Eina_Matrixsparse_Row *r,
unsigned long col)
{
Eina_Matrixsparse_Cell *c;
int dir;
2010-07-27 19:37:05 -07:00
if (!r->cols)
return NULL;
2010-07-27 19:37:05 -07:00
if (r->cols->col == col)
return r->cols;
else if (r->cols->col > col)
return NULL;
2010-07-27 19:37:05 -07:00
if (r->last_col->col == col)
return r->last_col;
else if (r->last_col->col < col)
return NULL;
2010-07-27 19:37:05 -07:00
if ((r->last_used) && (r->last_used->col == col))
return r->last_used;
_eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir);
assert(dir != 0);
if (dir > 0)
{
for (; c; c = c->next)
2010-07-27 19:37:05 -07:00
if (c->col == col)
{
((Eina_Matrixsparse_Row *)r)->last_used = c;
return c;
}
else if (c->col > col)
return NULL;
}
else if (dir < 0)
{
for (; c; c = c->prev)
if (c->col == col)
{
((Eina_Matrixsparse_Row *)r)->last_used = c;
return c;
}
else if (c->col < col)
2010-07-27 19:37:05 -07:00
return NULL;
}
return NULL;
}
static inline Eina_Matrixsparse_Cell *
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse *m,
unsigned long row,
unsigned long col)
{
Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row);
2010-07-27 19:37:05 -07:00
if (!r)
return NULL;
return _eina_matrixsparse_row_cell_idx_get(r, col);
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_idx_siblings_find(const Eina_Matrixsparse *m,
unsigned long row,
Eina_Matrixsparse_Row **p_prev,
Eina_Matrixsparse_Row **p_next)
{
Eina_Matrixsparse_Row *r;
int dir;
_eina_matrixsparse_row_find_parms_get(m, row, &r, &dir);
2010-07-27 19:37:05 -07:00
assert(dir != 0);
if (dir > 0)
{
for (; r; r = r->next)
2010-07-27 19:37:05 -07:00
if (r->row > row)
break;
assert(r != NULL);
2010-07-27 19:37:05 -07:00
*p_prev = r->prev;
*p_next = r;
}
else if (dir < 0)
{
for (; r; r = r->prev)
2010-07-27 19:37:05 -07:00
if (r->row < row)
break;
assert(r != NULL);
2010-07-27 19:37:05 -07:00
*p_prev = r;
*p_next = r->next;
}
}
static inline void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_cell_idx_siblings_find(const Eina_Matrixsparse_Row *r,
unsigned long col,
Eina_Matrixsparse_Cell **p_prev,
Eina_Matrixsparse_Cell **p_next)
{
Eina_Matrixsparse_Cell *c;
int dir;
_eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir);
2010-07-27 19:37:05 -07:00
assert(dir != 0);
if (dir > 0)
{
for (; c; c = c->next)
2010-07-27 19:37:05 -07:00
if (c->col > col)
break;
assert(c != NULL);
2010-07-27 19:37:05 -07:00
*p_prev = c->prev;
*p_next = c;
}
else if (dir < 0)
{
for (; c; c = c->prev)
2010-07-27 19:37:05 -07:00
if (c->col < col)
break;
assert(c != NULL);
2010-07-27 19:37:05 -07:00
*p_prev = c;
*p_next = c->next;
}
}
static inline Eina_Matrixsparse_Row *
_eina_matrixsparse_row_idx_add(Eina_Matrixsparse *m, unsigned long row)
{
Eina_Matrixsparse_Row *r = eina_mempool_malloc
2010-07-27 19:37:05 -07:00
(_eina_matrixsparse_row_mp, sizeof(Eina_Matrixsparse_Row));
if (!r)
return NULL;
if (!m->rows)
{
2010-07-27 19:37:05 -07:00
r->prev = NULL;
r->next = NULL;
m->rows = r;
m->last_row = r;
}
else if (row < m->rows->row)
{
2010-07-27 19:37:05 -07:00
r->prev = NULL;
r->next = m->rows;
m->rows->prev = r;
m->rows = r;
}
else if (row > m->last_row->row)
{
2010-07-27 19:37:05 -07:00
r->prev = m->last_row;
m->last_row->next = r;
r->next = NULL;
m->last_row = r;
}
else
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Row *prev = NULL, *next = NULL;
_eina_matrixsparse_row_idx_siblings_find(m, row, &prev, &next);
assert(prev != NULL);
assert(next != NULL);
2010-07-27 19:37:05 -07:00
r->prev = prev;
r->next = next;
prev->next = r;
next->prev = r;
}
r->cols = NULL;
r->last_col = NULL;
r->last_used = NULL;
r->row = row;
r->parent = m;
EINA_MAGIC_SET(r, EINA_MAGIC_MATRIXSPARSE_ROW);
m->last_used = r;
return r;
}
static inline Eina_Matrixsparse_Cell *
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_row_cell_idx_add(Eina_Matrixsparse_Row *r,
unsigned long col,
const void *data)
{
Eina_Matrixsparse_Cell *c = eina_mempool_malloc
2010-07-27 19:37:05 -07:00
(_eina_matrixsparse_cell_mp, sizeof(Eina_Matrixsparse_Cell));
if (!c)
return NULL;
if (!r->cols)
{
2010-07-27 19:37:05 -07:00
c->prev = NULL;
c->next = NULL;
r->cols = c;
r->last_col = c;
}
else if (col < r->cols->col)
{
2010-07-27 19:37:05 -07:00
c->prev = NULL;
c->next = r->cols;
r->cols->prev = c;
r->cols = c;
}
else if (col > r->last_col->col)
{
2010-07-27 19:37:05 -07:00
c->prev = r->last_col;
r->last_col->next = c;
c->next = NULL;
r->last_col = c;
}
else
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Cell *prev = NULL, *next = NULL;
_eina_matrixsparse_row_cell_idx_siblings_find(r, col, &prev, &next);
assert(prev != NULL);
assert(next != NULL);
2010-07-27 19:37:05 -07:00
c->prev = prev;
c->next = next;
prev->next = c;
next->prev = c;
}
c->data = (void *)data;
c->col = col;
c->parent = r;
EINA_MAGIC_SET(c, EINA_MAGIC_MATRIXSPARSE_CELL);
r->last_used = c;
return c;
}
static inline Eina_Bool
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_cell_idx_add(Eina_Matrixsparse *m,
unsigned long row,
unsigned long col,
const void *data)
{
Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row);
if (!r)
2010-07-27 19:37:05 -07:00
r = _eina_matrixsparse_row_idx_add(m, row);
if (!r)
2010-07-27 19:37:05 -07:00
return 0;
if (_eina_matrixsparse_row_cell_idx_add(r, col, data))
2010-07-27 19:37:05 -07:00
return 1;
if (r->cols)
2010-07-27 19:37:05 -07:00
return 0;
_eina_matrixsparse_row_unlink(r);
_eina_matrixsparse_row_free(r, m->free.func, m->free.user_data);
return 0;
}
/*============================================================================*
2010-07-27 19:37:05 -07:00
* Iterators *
*============================================================================*/
static Eina_Bool
_eina_matrixsparse_iterator_next(Eina_Matrixsparse_Iterator *it, void **data)
{
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE);
/* do not touch it->idx */
2010-07-27 19:37:05 -07:00
if (!it->ref.col)
return 0;
*data = (Eina_Matrixsparse_Cell *)it->ref.col;
it->ref.col = it->ref.col->next;
if (!it->ref.col)
{
2010-07-27 19:37:05 -07:00
it->ref.row = it->ref.row->next;
if (it->ref.row)
it->ref.col = it->ref.row->cols;
}
2010-07-27 19:37:05 -07:00
return 1;
}
static Eina_Matrixsparse *
_eina_matrixsparse_iterator_get_container(Eina_Matrixsparse_Iterator *it)
{
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL);
return (Eina_Matrixsparse *)it->m;
}
static void
_eina_matrixsparse_iterator_free(Eina_Matrixsparse_Iterator *it)
{
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it);
2010-07-27 19:37:05 -07:00
EINA_MAGIC_SET(it, EINA_MAGIC_NONE);
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE);
free(it);
}
static Eina_Bool
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_iterator_complete_next(
Eina_Matrixsparse_Iterator_Complete *it,
void **data)
{
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE);
if (it->idx.row >= it->m->size.rows)
2010-07-27 19:37:05 -07:00
return 0;
if (it->dummy.col.data)
2010-07-27 19:37:05 -07:00
ERR("Last iterator call changed dummy cell!");
if ((it->ref.col) &&
(it->ref.col->col == it->idx.col) &&
(it->ref.row->row == it->idx.row))
{
2010-07-27 19:37:05 -07:00
*data = (Eina_Matrixsparse_Cell *)it->ref.col;
it->ref.col = it->ref.col->next;
if (!it->ref.col)
{
it->ref.row = it->ref.row->next;
if (it->ref.row)
it->ref.col = it->ref.row->cols;
}
}
else
{
2010-07-27 19:37:05 -07:00
it->dummy.col.data = NULL;
it->dummy.col.col = it->idx.col;
it->dummy.row.row = it->idx.row;
*data = &it->dummy.col;
}
it->idx.col++;
if (it->idx.col == it->m->size.cols)
{
2010-07-27 19:37:05 -07:00
it->idx.col = 0;
it->idx.row++;
}
2010-07-27 19:37:05 -07:00
return 1;
}
static Eina_Matrixsparse *
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_iterator_complete_get_container(
Eina_Matrixsparse_Iterator_Complete *it)
{
2010-07-27 19:37:05 -07:00
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL);
return (Eina_Matrixsparse *)it->m;
}
static void
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_iterator_complete_free(
Eina_Matrixsparse_Iterator_Complete *it)
{
2010-07-27 19:37:05 -07:00
EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it);
if (it->dummy.col.data)
2010-07-27 19:37:05 -07:00
ERR("Last iterator call changed dummy cell!");
2010-07-27 19:37:05 -07:00
EINA_MAGIC_SET(it, EINA_MAGIC_NONE);
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE);
free(it);
}
/**
* @endcond
*/
/*============================================================================*
2010-07-27 19:37:05 -07:00
* Global *
*============================================================================*/
/**
* @internal
* @brief Initialize the matrixsparse module.
*
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function sets up the matrixsparse module of Eina. It is called by
* eina_init().
*
* This function creates mempool to speed up matrix rows and cells
* management, using EINA_MEMPOOL environment variable if it is set to
* choose the memory pool type to use.
*
* @see eina_init()
*/
Eina_Bool
eina_matrixsparse_init(void)
{
const char *choice, *tmp;
2010-07-27 19:37:05 -07:00
_eina_matrixsparse_log_dom = eina_log_domain_register("eina_matrixsparse",
EINA_LOG_COLOR_DEFAULT);
if (_eina_matrixsparse_log_dom < 0)
{
2010-07-27 19:37:05 -07:00
EINA_LOG_ERR("Could not register log domain: eina_matrixsparse");
return EINA_FALSE;
}
#ifdef EINA_DEFAULT_MEMPOOL
choice = "pass_through";
#else
choice = "chained_mempool";
#endif
tmp = getenv("EINA_MEMPOOL");
if (tmp && tmp[0])
2010-07-27 19:37:05 -07:00
choice = tmp;
_eina_matrixsparse_cell_mp = eina_mempool_add
2010-07-27 19:37:05 -07:00
(choice,
"matrixsparse_cell",
NULL,
sizeof (Eina_Matrixsparse_Cell),
32);
if (!_eina_matrixsparse_cell_mp)
{
2010-07-27 19:37:05 -07:00
ERR(
"Mempool for matrixsparse_cell cannot be allocated in matrixsparse init.");
goto on_init_fail;
}
_eina_matrixsparse_row_mp = eina_mempool_add
(choice, "matrixsparse_row", NULL, sizeof (Eina_Matrixsparse_Row), 32);
if (!_eina_matrixsparse_row_mp)
{
2010-07-27 19:37:05 -07:00
ERR(
"Mempool for matrixsparse_row cannot be allocated in matrixsparse init.");
goto on_init_fail;
}
2010-07-27 19:37:05 -07:00
#define EMS(n) eina_magic_string_static_set(n, n ## _STR)
EMS(EINA_MAGIC_MATRIXSPARSE);
EMS(EINA_MAGIC_MATRIXSPARSE_ROW);
EMS(EINA_MAGIC_MATRIXSPARSE_CELL);
EMS(EINA_MAGIC_MATRIXSPARSE_ITERATOR);
EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR);
EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR);
EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR);
EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR);
#undef EMS
return EINA_TRUE;
2010-07-27 19:37:05 -07:00
on_init_fail:
eina_log_domain_unregister(_eina_matrixsparse_log_dom);
_eina_matrixsparse_log_dom = -1;
return EINA_FALSE;
}
/**
* @internal
* @brief Shut down the matrixsparse module.
*
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function shuts down the matrixsparse module set up by
* eina_matrixsparse_init(). It is called by eina_shutdown().
*
* @see eina_shutdown()
*/
Eina_Bool
eina_matrixsparse_shutdown(void)
{
eina_mempool_del(_eina_matrixsparse_row_mp);
eina_mempool_del(_eina_matrixsparse_cell_mp);
eina_log_domain_unregister(_eina_matrixsparse_log_dom);
_eina_matrixsparse_log_dom = -1;
return EINA_TRUE;
}
/*============================================================================*
2010-07-27 19:37:05 -07:00
* API *
*============================================================================*/
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Matrixsparse *
2010-07-27 19:37:05 -07:00
eina_matrixsparse_new(unsigned long rows, unsigned long cols, void (*free_func)(
void *user_data,
void *cell_data), const void *user_data)
{
Eina_Matrixsparse *m;
EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, NULL);
m = malloc(sizeof(Eina_Matrixsparse));
if (!m) return NULL;
EINA_MAGIC_SET(m, EINA_MAGIC_MATRIXSPARSE);
m->rows = NULL;
m->last_row = NULL;
m->last_used = NULL;
m->size.rows = rows;
m->size.cols = cols;
m->free.func = free_func;
m->free.user_data = (void *)user_data;
return m;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void
eina_matrixsparse_free(Eina_Matrixsparse *m)
{
void (*free_func)(void *, void *);
void *user_data;
Eina_Matrixsparse_Row *r;
if (!m)
return;
EINA_MAGIC_CHECK_MATRIXSPARSE(m);
free_func = m->free.func;
user_data = m->free.user_data;
r = m->rows;
while (r)
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Row *r_aux = r;
r = r->next;
_eina_matrixsparse_row_free(r_aux, free_func, user_data);
}
EINA_MAGIC_SET(m, EINA_MAGIC_NONE);
free(m);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void
2010-07-27 19:37:05 -07:00
eina_matrixsparse_size_get(const Eina_Matrixsparse *m,
unsigned long *rows,
unsigned long *cols)
{
2010-07-27 19:37:05 -07:00
if (rows)
*rows = 0;
if (cols)
*cols = 0;
EINA_MAGIC_CHECK_MATRIXSPARSE(m);
2010-07-27 19:37:05 -07:00
if (rows)
*rows = m->size.rows;
if (cols)
*cols = m->size.cols;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_size_set(Eina_Matrixsparse *m,
unsigned long rows,
unsigned long cols)
{
Eina_Bool update_last_used_row;
Eina_Matrixsparse_Row *r;
void (*free_func)(void *, void *);
void *user_data;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, 0);
2010-07-27 19:37:05 -07:00
if ((rows == m->size.rows) && (cols == m->size.cols))
return 1;
update_last_used_row = ((m->last_used) && (m->last_used->row >= rows));
free_func = m->free.func;
user_data = m->free.user_data;
r = m->last_row;
while (r && r->row >= rows)
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Row *r_aux = r;
r = r->prev;
_eina_matrixsparse_row_free(r_aux, free_func, user_data);
}
if (!r)
{
2010-07-27 19:37:05 -07:00
m->last_row = NULL;
m->rows = NULL;
}
else if (r != m->last_row)
{
2010-07-27 19:37:05 -07:00
r->next = NULL;
m->last_row = r;
}
if (update_last_used_row)
2010-07-27 19:37:05 -07:00
m->last_used = m->last_row;
r = m->rows;
while (r)
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Cell *c = r->last_col;
Eina_Bool update_last_used_col;
update_last_used_col = ((r->last_used) && (r->last_used->col >= cols));
while (c && c->col >= cols)
{
Eina_Matrixsparse_Cell *c_aux = c;
c = c->prev;
_eina_matrixsparse_cell_free(c_aux, free_func, user_data);
}
if (!c)
{
Eina_Matrixsparse_Row *r_aux = r;
r->cols = NULL;
r->last_col = NULL;
if (r->next)
r->next->prev = r->prev;
else
m->last_row = r->prev;
if (r->prev)
r->prev->next = r->next;
else
m->rows = r->next;
r = r->next;
_eina_matrixsparse_row_free(r_aux, free_func, user_data);
if ((update_last_used_row) && (m->last_used == r_aux))
m->last_used = r;
2010-07-27 19:37:05 -07:00
}
else
{
if (c != r->last_col)
{
c->next = NULL;
r->last_col = c;
}
if (update_last_used_col)
r->last_used = r->last_col;
r = r->next;
}
}
update_last_used_row = 0;
if (m->last_used)
{
2010-07-27 19:37:05 -07:00
if (m->last_row)
update_last_used_row = m->last_used->row > m->last_row->row;
else
update_last_used_row = 1;
}
if (update_last_used_row)
2010-07-27 19:37:05 -07:00
m->last_used = m->last_row;
m->size.rows = rows;
m->size.cols = cols;
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse *m,
unsigned long row,
unsigned long col,
Eina_Matrixsparse_Cell **cell)
{
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(cell, 0);
*cell = NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0);
*cell = _eina_matrixsparse_cell_idx_get(m, row, col);
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void *
eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell *cell)
{
EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, NULL);
return cell->data;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void *
2010-07-27 19:37:05 -07:00
eina_matrixsparse_data_idx_get(const Eina_Matrixsparse *m,
unsigned long row,
unsigned long col)
{
Eina_Matrixsparse_Cell *c;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, NULL);
c = _eina_matrixsparse_cell_idx_get(m, row, col);
2010-07-27 19:37:05 -07:00
if (c)
return c->data;
else
return NULL;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_cell_position_get(const Eina_Matrixsparse_Cell *cell,
unsigned long *row,
unsigned long *col)
{
2010-07-27 19:37:05 -07:00
if (row)
*row = 0;
if (col)
*col = 0;
EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0);
EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0);
2010-07-27 19:37:05 -07:00
if (row)
*row = cell->parent->row;
if (col)
*col = cell->col;
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_cell_data_replace(Eina_Matrixsparse_Cell *cell,
const void *data,
void **p_old)
{
2010-07-27 19:37:05 -07:00
if (p_old)
*p_old = NULL;
EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0);
2010-07-27 19:37:05 -07:00
if (p_old)
*p_old = cell->data;
cell->data = (void *)data;
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_matrixsparse_cell_data_set(Eina_Matrixsparse_Cell *cell, const void *data)
{
Eina_Matrixsparse *m;
EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0);
EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0);
EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0);
m = cell->parent->parent;
if (m->free.func)
2010-07-27 19:37:05 -07:00
m->free.func(m->free.user_data, cell->data);
cell->data = (void *)data;
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_data_idx_replace(Eina_Matrixsparse *m,
unsigned long row,
unsigned long col,
const void *data,
void **p_old)
{
Eina_Matrixsparse_Cell *cell;
2010-07-27 19:37:05 -07:00
if (p_old)
*p_old = NULL;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0);
cell = _eina_matrixsparse_cell_idx_get(m, row, col);
if (cell)
{
2010-07-27 19:37:05 -07:00
if (p_old)
*p_old = cell->data;
cell->data = (void *)data;
return 1;
}
return _eina_matrixsparse_cell_idx_add(m, row, col, data);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_data_idx_set(Eina_Matrixsparse *m,
unsigned long row,
unsigned long col,
const void *data)
{
Eina_Matrixsparse_Cell *cell;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0);
cell = _eina_matrixsparse_cell_idx_get(m, row, col);
if (cell)
{
2010-07-27 19:37:05 -07:00
if (m->free.func)
m->free.func(m->free.user_data, cell->data);
cell->data = (void *)data;
return 1;
}
return _eina_matrixsparse_cell_idx_add(m, row, col, data);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_matrixsparse_row_idx_clear(Eina_Matrixsparse *m, unsigned long row)
{
Eina_Matrixsparse_Row *r;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0);
r = _eina_matrixsparse_row_idx_get(m, row);
2010-07-27 19:37:05 -07:00
if (!r)
return 1;
_eina_matrixsparse_row_unlink(r);
_eina_matrixsparse_row_free(r, m->free.func, m->free.user_data);
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_matrixsparse_column_idx_clear(Eina_Matrixsparse *m, unsigned long col)
{
Eina_Matrixsparse_Row *r;
void (*free_func)(void *, void *);
void *user_data;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0);
free_func = m->free.func;
user_data = m->free.user_data;
for (r = m->rows; r; )
{
2010-07-27 19:37:05 -07:00
Eina_Matrixsparse_Row *r_aux = r;
Eina_Matrixsparse_Cell *c;
c = _eina_matrixsparse_row_cell_idx_get(r, col);
r = r->next;
if (!c)
continue;
if ((r_aux->cols != c) || (r_aux->last_col != c))
{
_eina_matrixsparse_cell_unlink(c);
_eina_matrixsparse_cell_free(c, free_func, user_data);
}
else
{
_eina_matrixsparse_row_unlink(r_aux);
_eina_matrixsparse_row_free(r_aux, free_func, user_data);
}
}
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
2010-07-27 19:37:05 -07:00
eina_matrixsparse_cell_idx_clear(Eina_Matrixsparse *m,
unsigned long row,
unsigned long col)
{
Eina_Matrixsparse_Cell *c;
EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0);
EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0);
c = _eina_matrixsparse_cell_idx_get(m, row, col);
2010-07-27 19:37:05 -07:00
if (!c)
return 1;
_eina_matrixsparse_cell_unlink(c);
_eina_matrixsparse_cell_free(c, m->free.func, m->free.user_data);
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_matrixsparse_cell_clear(Eina_Matrixsparse_Cell *cell)
{
Eina_Matrixsparse *m;
EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0);
EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0);
EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0);
m = cell->parent->parent;
_eina_matrixsparse_cell_unlink(cell);
_eina_matrixsparse_cell_free(cell, m->free.func, m->free.user_data);
return 1;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Iterator *
eina_matrixsparse_iterator_new(const Eina_Matrixsparse *m)
{
Eina_Matrixsparse_Iterator *it;
it = calloc(1, sizeof(*it));
if (!it) return NULL;
2010-07-27 19:37:05 -07:00
EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR);
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->m = m;
it->ref.row = m->rows;
it->ref.col = m->rows ? m->rows->cols : NULL;
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_matrixsparse_iterator_next);
2010-07-27 19:37:05 -07:00
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_eina_matrixsparse_iterator_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(_eina_matrixsparse_iterator_free);
return &it->iterator;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Iterator *
eina_matrixsparse_iterator_complete_new(const Eina_Matrixsparse *m)
{
Eina_Matrixsparse_Iterator_Complete *it;
it = calloc(1, sizeof(*it));
if (!it) return NULL;
2010-07-27 19:37:05 -07:00
EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR);
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->m = m;
it->idx.row = 0;
it->idx.col = 0;
it->ref.row = m->rows;
it->ref.col = m->rows ? m->rows->cols : NULL;
it->dummy.row.next = it->dummy.row.prev = NULL;
it->dummy.row.cols = it->dummy.row.last_col = it->dummy.row.last_used = NULL;
it->dummy.row.parent = (Eina_Matrixsparse *)m;
EINA_MAGIC_SET(&it->dummy.row, EINA_MAGIC_MATRIXSPARSE_ROW);
it->dummy.col.next = it->dummy.col.prev = NULL;
it->dummy.col.data = NULL;
it->dummy.col.parent = &it->dummy.row;
EINA_MAGIC_SET(&it->dummy.col, EINA_MAGIC_MATRIXSPARSE_CELL);
it->iterator.version = EINA_ITERATOR_VERSION;
2010-07-27 19:37:05 -07:00
it->iterator.next = FUNC_ITERATOR_NEXT(
_eina_matrixsparse_iterator_complete_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_eina_matrixsparse_iterator_complete_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(
_eina_matrixsparse_iterator_complete_free);
return &it->iterator;
}