Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-vector.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2015 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <errno.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
58 typedef struct sol_vector {
59  void *data;
60  uint16_t len;
61  uint16_t elem_size;
62 } sol_vector;
63 
64 
70 #define SOL_VECTOR_INIT(TYPE) { NULL, 0, sizeof(TYPE) }
71 
78 void sol_vector_init(struct sol_vector *v, uint16_t elem_size);
79 
92 void *sol_vector_append(struct sol_vector *v);
93 
107 void *sol_vector_append_n(struct sol_vector *v, uint16_t n);
108 
125 static inline void *
126 sol_vector_get_no_check(const struct sol_vector *v, uint16_t i)
127 {
128  const unsigned char *data;
129 
130  data = (const unsigned char *)v->data;
131 
132  return (void *)&data[v->elem_size * i];
133 }
134 
145 static inline void *
146 sol_vector_get(const struct sol_vector *v, uint16_t i)
147 {
148  if (i >= v->len)
149  return NULL;
150 
151  return sol_vector_get_no_check(v, i);
152 }
153 
166 int sol_vector_del(struct sol_vector *v, uint16_t i);
167 
180 int sol_vector_del_element(struct sol_vector *v, const void *elem);
181 
191 static inline int
193 {
194  if (v->len == 0)
195  return 0;
196  return sol_vector_del(v, v->len - 1);
197 }
198 
211 int sol_vector_del_range(struct sol_vector *v, uint16_t start, uint16_t len);
212 
222 void sol_vector_clear(struct sol_vector *v);
223 
235 static inline void *
237 {
238  void *data = v->data;
239 
240  v->data = NULL;
241  v->len = 0;
242  return data;
243 }
244 
253 #define SOL_VECTOR_FOREACH_IDX(vector, itrvar, idx) \
254  for (idx = 0; \
255  idx < (vector)->len && (itrvar = (__typeof__(itrvar))sol_vector_get_no_check((vector), idx), true); \
256  idx++)
257 
267 #define SOL_VECTOR_FOREACH_IDX_UNTIL(vector, itrvar, idx, until) \
268  for (idx = 0; \
269  idx < until && (itrvar = (__typeof__(itrvar))sol_vector_get_no_check((vector), idx), true); \
270  idx++)
271 
280 #define SOL_VECTOR_FOREACH_REVERSE_IDX(vector, itrvar, idx) \
281  for (idx = (vector)->len - 1; \
282  idx != ((__typeof__(idx)) - 1) && (itrvar = (__typeof__(itrvar))sol_vector_get_no_check((vector), idx), true); \
283  idx--)
284 
310 typedef struct sol_ptr_vector {
311  struct sol_vector base;
313 
318 #define SOL_PTR_VECTOR_INIT { { NULL, 0, sizeof(void *) } }
319 
325 static inline void
327 {
328  sol_vector_init(&pv->base, sizeof(void *));
329 }
330 
340 int sol_ptr_vector_init_n(struct sol_ptr_vector *pv, uint16_t n);
341 
351 static inline uint16_t
353 {
354  return pv->base.len;
355 }
356 
369 int sol_ptr_vector_append(struct sol_ptr_vector *pv, const void *ptr);
370 
387 static inline void *
388 sol_ptr_vector_get_no_check(const struct sol_ptr_vector *pv, uint16_t i)
389 {
390  void **data;
391 
392  data = (void **)sol_vector_get_no_check(&pv->base, i);
393  return *data;
394 }
395 
406 static inline void *
407 sol_ptr_vector_get(const struct sol_ptr_vector *pv, uint16_t i)
408 {
409  if (i >= pv->base.len)
410  return NULL;
411 
412  return sol_ptr_vector_get_no_check(pv, i);
413 }
414 
426 int sol_ptr_vector_set(struct sol_ptr_vector *pv, uint16_t i, const void *ptr);
427 
455 int32_t sol_ptr_vector_insert_sorted(struct sol_ptr_vector *pv, const void *ptr, int (*compare_cb)(const void *data1, const void *data2));
456 
477 int32_t sol_ptr_vector_update_sorted(struct sol_ptr_vector *pv, uint16_t i, int (*compare_cb)(const void *data1, const void *data2));
478 
503 int sol_ptr_vector_insert_at(struct sol_ptr_vector *pv, uint16_t i, const void *ptr);
504 
522 int sol_ptr_vector_remove(struct sol_ptr_vector *pv, const void *ptr);
523 
540 static inline int
541 sol_ptr_vector_del(struct sol_ptr_vector *pv, uint16_t i)
542 {
543  return sol_vector_del(&pv->base, i);
544 }
545 
558 static inline int
559 sol_ptr_vector_del_range(struct sol_ptr_vector *pv, uint16_t start, uint16_t len)
560 {
561  return sol_vector_del_range(&pv->base, start, len);
562 }
563 
577 int sol_ptr_vector_del_element(struct sol_ptr_vector *pv, const void *elem);
578 
588 static inline int
590 {
591  if (pv->base.len == 0)
592  return 0;
593  return sol_ptr_vector_del(pv, pv->base.len - 1);
594 }
595 
606 static inline void *
607 sol_ptr_vector_steal(struct sol_ptr_vector *pv, uint16_t i)
608 {
609  void *result = sol_ptr_vector_get(pv, i);
610 
611  sol_ptr_vector_del(pv, i);
612  return result;
613 }
614 
624 static inline void *
626 {
627  if (pv->base.len == 0)
628  return NULL;
629  return sol_ptr_vector_steal(pv, pv->base.len - 1);
630 }
631 
641 static inline void
643 {
644  sol_vector_clear(&pv->base);
645 }
646 
658 static inline void *
660 {
661  return sol_vector_steal_data(&pv->base);
662 }
663 
672 #define SOL_PTR_VECTOR_FOREACH_IDX(vector, itrvar, idx) \
673  for (idx = 0; \
674  idx < (vector)->base.len && \
675  ((itrvar = (__typeof__(itrvar))sol_ptr_vector_get_no_check((vector), idx)), true); \
676  idx++)
677 
687 #define SOL_PTR_VECTOR_FOREACH_IDX_UNTIL(vector, itrvar, idx, until) \
688  for (idx = 0; \
689  idx < until && \
690  ((itrvar = (__typeof__(itrvar))sol_ptr_vector_get_no_check((vector), idx)), true); \
691  idx++)
692 
701 #define SOL_PTR_VECTOR_FOREACH_REVERSE_IDX(vector, itrvar, idx) \
702  for (idx = (vector)->base.len - 1; \
703  idx != ((__typeof__(idx)) - 1) && \
704  (itrvar = (__typeof__(itrvar))sol_ptr_vector_get_no_check((vector), idx), true); \
705  idx--)
706 
726 static inline int32_t
727 sol_ptr_vector_find_last(const struct sol_ptr_vector *pv, const void *elem)
728 {
729  uint16_t i;
730  const void *p;
731 
733  if (elem == p)
734  return i;
735  }
736 
737  return -ENODATA;
738 }
739 
759 static inline int32_t
760 sol_ptr_vector_find_first(const struct sol_ptr_vector *pv, const void *elem)
761 {
762  uint16_t i;
763  const void *p;
764 
765  SOL_PTR_VECTOR_FOREACH_IDX (pv, p, i) {
766  if (elem == p)
767  return i;
768  }
769 
770  return -ENODATA;
771 }
772 
797 static inline int32_t
798 sol_ptr_vector_match_first(const struct sol_ptr_vector *pv, const void *tempt, int (*compare_cb)(const void *data1, const void *data2))
799 {
800  uint16_t i;
801  const void *p;
802 
803  SOL_PTR_VECTOR_FOREACH_IDX (pv, p, i) {
804  if (compare_cb(tempt, p) == 0)
805  return i;
806  }
807 
808  return -ENODATA;
809 }
810 
835 static inline int32_t
836 sol_ptr_vector_match_last(const struct sol_ptr_vector *pv, const void *tempt, int (*compare_cb)(const void *data1, const void *data2))
837 {
838  uint16_t i;
839  const void *p;
840 
842  if (compare_cb(tempt, p) == 0)
843  return i;
844  }
845 
846  return -ENODATA;
847 }
848 
877 int32_t sol_ptr_vector_match_sorted(const struct sol_ptr_vector *pv, const void *tempt, int (*compare_cb)(const void *data1, const void *data2));
878 
912 static inline int32_t
913 sol_ptr_vector_find_sorted(const struct sol_ptr_vector *pv, const void *elem, int (*compare_cb)(const void *data1, const void *data2))
914 {
915  uint16_t i;
916  int32_t r;
917 
918  r = sol_ptr_vector_match_sorted(pv, elem, compare_cb);
919  if (r < 0)
920  return r;
921 
922  for (i = r; i < pv->base.len; i++) {
923  const void *other = sol_ptr_vector_get_no_check(pv, i);
924 
925  if (compare_cb(elem, other) != 0)
926  break;
927 
928  if (elem == other)
929  return i;
930  }
931 
932  for (i = r; i > 0; i--) {
933  const void *other = sol_ptr_vector_get_no_check(pv, i - 1);
934 
935  if (compare_cb(elem, other) != 0)
936  break;
937 
938  if (elem == other)
939  return i - 1;
940  }
941 
942  return -ENODATA;
943 }
944 
968 static inline int32_t
969 sol_ptr_vector_find_last_sorted(const struct sol_ptr_vector *pv, const void *elem, int (*compare_cb)(const void *data1, const void *data2))
970 {
971  uint16_t i;
972  int32_t r, found_i = -ENODATA;
973 
974  r = sol_ptr_vector_match_sorted(pv, elem, compare_cb);
975  if (r < 0)
976  return r;
977 
978  for (i = r; i < pv->base.len; i++) {
979  const void *other = sol_ptr_vector_get_no_check(pv, i);
980 
981  if (compare_cb(elem, other) != 0)
982  break;
983 
984  if (elem == other)
985  found_i = i;
986  }
987 
988  if (found_i >= 0)
989  return found_i;
990 
991  for (i = r; i > 0; i--) {
992  const void *other = sol_ptr_vector_get_no_check(pv, i - 1);
993 
994  if (compare_cb(elem, other) != 0)
995  break;
996 
997  if (elem == other)
998  return i - 1;
999  }
1000 
1001  return -ENODATA;
1002 }
1003 
1027 static inline int32_t
1028 sol_ptr_vector_find_first_sorted(const struct sol_ptr_vector *pv, const void *elem, int (*compare_cb)(const void *data1, const void *data2))
1029 {
1030  uint16_t i;
1031  int32_t r, found_i = -ENODATA;
1032 
1033  r = sol_ptr_vector_match_sorted(pv, elem, compare_cb);
1034  if (r < 0)
1035  return r;
1036 
1037  for (i = r;;) {
1038  const void *other = sol_ptr_vector_get_no_check(pv, i);
1039 
1040  if (compare_cb(elem, other) != 0)
1041  break;
1042 
1043  if (elem == other)
1044  found_i = i;
1045 
1046  if (i == 0)
1047  break;
1048  i--;
1049  }
1050 
1051  if (found_i >= 0)
1052  return found_i;
1053 
1054  for (i = r; i + 1 < pv->base.len; i++) {
1055  const void *other = sol_ptr_vector_get_no_check(pv, i + 1);
1056 
1057  if (compare_cb(elem, other) != 0)
1058  break;
1059 
1060  if (elem == other)
1061  return i + 1;
1062  }
1063 
1064  return -ENODATA;
1065 }
1066 
1071 #ifdef __cplusplus
1072 }
1073 #endif
struct sol_vector base
Definition: sol-vector.h:311
static void * sol_ptr_vector_steal(struct sol_ptr_vector *pv, uint16_t i)
Remove and return the element at index i from the vector.
Definition: sol-vector.h:607
static int sol_vector_del_last(struct sol_vector *v)
Remove the last element from the vector.
Definition: sol-vector.h:192
static void * sol_vector_get_no_check(const struct sol_vector *v, uint16_t i)
Return the element of the vector at the given index (no safety checks).
Definition: sol-vector.h:126
static int32_t sol_ptr_vector_find_last_sorted(const struct sol_ptr_vector *pv, const void *elem, int(*compare_cb)(const void *data1, const void *data2))
Find the last occurrence of elem in the sorted vector pv.
Definition: sol-vector.h:969
#define SOL_PTR_VECTOR_FOREACH_IDX(vector, itrvar, idx)
Macro to iterate over the pointer vector easily.
Definition: sol-vector.h:672
int sol_ptr_vector_del_element(struct sol_ptr_vector *pv, const void *elem)
Remove all occurrences of elem from the vector pv.
static int32_t sol_ptr_vector_find_sorted(const struct sol_ptr_vector *pv, const void *elem, int(*compare_cb)(const void *data1, const void *data2))
Find the exact occurrence of elem in the sorted vector pv.
Definition: sol-vector.h:913
static void sol_ptr_vector_clear(struct sol_ptr_vector *pv)
Delete all elements from the vector.
Definition: sol-vector.h:642
static int32_t sol_ptr_vector_match_last(const struct sol_ptr_vector *pv, const void *tempt, int(*compare_cb)(const void *data1, const void *data2))
Match for the last occurrence matching template tempt.
Definition: sol-vector.h:836
void * sol_vector_append_n(struct sol_vector *v, uint16_t n)
Append n elements to the end of the vector.
int32_t sol_ptr_vector_insert_sorted(struct sol_ptr_vector *pv, const void *ptr, int(*compare_cb)(const void *data1, const void *data2))
Insert a pointer in the pointer vector, using the given comparison function to determine its position...
int sol_ptr_vector_init_n(struct sol_ptr_vector *pv, uint16_t n)
Initializes a sol_ptr_vector structure and preallocates n elements.
static int32_t sol_ptr_vector_find_last(const struct sol_ptr_vector *pv, const void *elem)
Find the last occurrence of elem from the vector pv.
Definition: sol-vector.h:727
static int sol_ptr_vector_del_range(struct sol_ptr_vector *pv, uint16_t start, uint16_t len)
Remove an range of pointers from the vector.
Definition: sol-vector.h:559
int sol_ptr_vector_remove(struct sol_ptr_vector *pv, const void *ptr)
Remove an pointer from the vector.
static int32_t sol_ptr_vector_find_first_sorted(const struct sol_ptr_vector *pv, const void *elem, int(*compare_cb)(const void *data1, const void *data2))
Find the first occurrence of elem in the sorted vector pv.
Definition: sol-vector.h:1028
uint16_t elem_size
Size of each element in bytes.
Definition: sol-vector.h:61
static void * sol_ptr_vector_steal_data(struct sol_ptr_vector *pv)
Steal the memory holding the elements of the vector.
Definition: sol-vector.h:659
static void * sol_ptr_vector_get(const struct sol_ptr_vector *pv, uint16_t i)
Return the element of the vector at the given index.
Definition: sol-vector.h:407
struct sol_ptr_vector sol_ptr_vector
Soletta pointer vector is a wrapper around vector with an API more convenient to handle pointers...
int sol_ptr_vector_set(struct sol_ptr_vector *pv, uint16_t i, const void *ptr)
Set the element at index i to be ptr.
int sol_vector_del_element(struct sol_vector *v, const void *elem)
Remove an element from the vector.
static int sol_ptr_vector_del(struct sol_ptr_vector *pv, uint16_t i)
Remove the pointer of index i from the vector.
Definition: sol-vector.h:541
int32_t sol_ptr_vector_update_sorted(struct sol_ptr_vector *pv, uint16_t i, int(*compare_cb)(const void *data1, const void *data2))
Update sorted pointer vector so the element is still in order.
uint16_t len
Vector length.
Definition: sol-vector.h:60
int sol_ptr_vector_insert_at(struct sol_ptr_vector *pv, uint16_t i, const void *ptr)
Insert a pointer in the pointer vector at a given position.
void * data
Vector data.
Definition: sol-vector.h:59
void sol_vector_init(struct sol_vector *v, uint16_t elem_size)
Initializes a sol_vector structure.
static uint16_t sol_ptr_vector_get_len(const struct sol_ptr_vector *pv)
Returns the number of pointers stored in the vector.
Definition: sol-vector.h:352
static void * sol_vector_steal_data(struct sol_vector *v)
Steal the memory holding the elements of the vector.
Definition: sol-vector.h:236
struct sol_vector sol_vector
Soletta vector is an array that grows dynamically.
static void sol_ptr_vector_init(struct sol_ptr_vector *pv)
Initializes a sol_ptr_vector structure.
Definition: sol-vector.h:326
int32_t sol_ptr_vector_match_sorted(const struct sol_ptr_vector *pv, const void *tempt, int(*compare_cb)(const void *data1, const void *data2))
Match for occurrence matching template tempt in the sorted vector pv.
Soletta pointer vector is a wrapper around vector with an API more convenient to handle pointers...
Definition: sol-vector.h:310
int sol_vector_del_range(struct sol_vector *v, uint16_t start, uint16_t len)
Remove an range of element from the vector.
int sol_vector_del(struct sol_vector *v, uint16_t i)
Remove an element from the vector.
Soletta vector is an array that grows dynamically.
Definition: sol-vector.h:58
static void * sol_ptr_vector_steal_last(struct sol_ptr_vector *pv)
Remove and return the last element from the vector.
Definition: sol-vector.h:625
#define SOL_PTR_VECTOR_FOREACH_REVERSE_IDX(vector, itrvar, idx)
Macro to iterate over the pointer vector easily in the reverse order.
Definition: sol-vector.h:701
static int32_t sol_ptr_vector_find_first(const struct sol_ptr_vector *pv, const void *elem)
Find the first occurrence of elem from the vector pv.
Definition: sol-vector.h:760
static int32_t sol_ptr_vector_match_first(const struct sol_ptr_vector *pv, const void *tempt, int(*compare_cb)(const void *data1, const void *data2))
Match for the first occurrence matching template tempt.
Definition: sol-vector.h:798
void sol_vector_clear(struct sol_vector *v)
Delete all elements from the vector.
static void * sol_ptr_vector_get_no_check(const struct sol_ptr_vector *pv, uint16_t i)
Return the element of the vector at the given index (no safety checks).
Definition: sol-vector.h:388
static int sol_ptr_vector_del_last(struct sol_ptr_vector *pv)
Remove the last element from the vector.
Definition: sol-vector.h:589
void * sol_vector_append(struct sol_vector *v)
Append an element to the end of the vector.
int sol_ptr_vector_append(struct sol_ptr_vector *pv, const void *ptr)
Append a pointer to the end of the vector.
static void * sol_vector_get(const struct sol_vector *v, uint16_t i)
Return the element of the vector at the given index.
Definition: sol-vector.h:146