Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
glib_utils.h
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18#ifndef DT_COMMON_GLIB_UTILS_H
19#define DT_COMMON_GLIB_UTILS_H
20
21/* Small GLib convenience helpers (GList traversal, string splicing). Application-free
22 * on purpose: include this instead of darktable.h. */
23
24#include "system/macros.h"
25
26#include <glib.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32// a few macros and helper functions to speed up certain frequently-used GLib operations
33#define g_list_is_singleton(list) ((list) && (!(list)->next))
34static inline gboolean g_list_shorter_than(const GList *list, unsigned len)
35{
36 // instead of scanning the full list to compute its length and then comparing against the limit,
37 // bail out as soon as the limit is reached. Usage: g_list_shorter_than(l,4) instead of g_list_length(l)<4
38 while (len-- > 0)
39 {
40 if (!list) return TRUE;
41 list = g_list_next(list);
42 }
43 return FALSE;
44}
45
46// advance the list by one position, unless already at the final node
47static inline GList *g_list_next_bounded(GList *list)
48{
49 return g_list_next(list) ? g_list_next(list) : list;
50}
51
52static inline const GList *g_list_next_wraparound(const GList *list, const GList *head)
53{
54 return g_list_next(list) ? g_list_next(list) : head;
55}
56
57static inline const GList *g_list_prev_wraparound(const GList *list)
58{
59 // return the prior element of the list, unless already on the first element; in that case, return the last
60 // element of the list.
61 return g_list_previous(list) ? g_list_previous(list) : g_list_last((GList*)list);
62}
63
64static inline gchar *dt_string_replace(const char *string, const char *to_replace)
65{
66 if(IS_NULL_PTR(string) || IS_NULL_PTR(to_replace)) return NULL;
67 gchar **split = g_strsplit(string, to_replace, -1);
68 gchar *text = g_strjoinv("", split);
70 return text;
71}
72
73#ifdef __cplusplus
74}
75#endif
76
77#endif // DT_COMMON_GLIB_UTILS_H
78
79// clang-format off
80// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
81// vim: shiftwidth=2 expandtab tabstop=2 cindent
82// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
83// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
static gchar * dt_string_replace(const char *string, const char *to_replace)
Definition glib_utils.h:64
static const GList * g_list_next_wraparound(const GList *list, const GList *head)
Definition glib_utils.h:52
static const GList * g_list_prev_wraparound(const GList *list)
Definition glib_utils.h:57
static GList * g_list_next_bounded(GList *list)
Definition glib_utils.h:47
static gboolean g_list_shorter_than(const GList *list, unsigned len)
Definition glib_utils.h:34
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65