~ubuntu-branches/debian/experimental/qtcurve/experimental

« back to all changes in this revision

Viewing changes to lib/utils/utils.h

  • Committer: Package Import Robot
  • Author(s): Boris Pek, Thanks to Scarlett Clark
  • Date: 2015-07-26 04:17:05 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20150726041705-yuxbierbpely1fvp
Tags: 1.8.18+git20150711-a3fff13-1
* Upstream Git snapshot (1.8.18-242-ga3fff13) is taken from:
  http://quickgit.kde.org/?p=qtcurve.git
* Localization files are taken from last stable release (1.8.18).
* Fixed in upstream:
  - gtk2-engines-qtcurve: inkscape 0.91 crashes after palette mouse-over
    (Closes: #786831)
  - gtk2-engines-qtcurve: massive memory leak in mysql-workbench
    (Closes: #682162)
* Update debian/patches:
  - delete qt53-build-fix.diff (fixed in upstream)
  - add enable-translations.patch
* Update debian/control:
  - bump Standards-Version to 3.9.6 (was 3.9.5): no changes required
  - update Build-Depends for transition from KDE4 to KF5:
    + delete dependencies from: kdebase-workspace-dev and qtdeclarative5-dev
    + add dependencies from: extra-cmake-modules, kio-dev,
      libkf5archive-dev, libkf5config-dev, libkf5configwidgets-dev,
      libkf5i18n-dev, libkf5kdelibs4support-dev, libkf5widgetsaddons-dev,
      libkf5xmlgui-dev, libqt5x11extras5-dev, libxcb1-dev, pkg-config
      [Thanks to Scarlett Clark]
  - delete package kwin-style-qtcurve: it is not available for KF5 yet
    (LP: #1452218)
  - package kde-style-qtcurve now provides package kde-style-qtcurve-qt4
  - package kde-style-qtcurve is "Multi-Arch: same" now
  - metapackage qtcurve now depends on kde-style-qtcurve-qt5 and recommends
    kwin-decoration-oxygen, oxygen-icon-theme and oxygencursors
* Update debian/rules:
  - build using kf5 libraries instead of kde4
  - update configure flags
  - use xz compression in packages
* Update debian/kde-style-qtcurve.install:
  there are no KDE4 related files anymore.
* Update debian/kde-style-qtcurve-qt5.install.
* Update debian/copyright.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
 
 *   Copyright 2013 - 2014 Yichao Yu <yyc1992@gmail.com>                     *
 
2
 *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
3
3
 *                                                                           *
4
4
 *   This program is free software; you can redistribute it and/or modify    *
5
5
 *   it under the terms of the GNU Lesser General Public License as          *
28
28
#include <stdio.h>
29
29
#include <stddef.h>
30
30
#include <math.h>
31
 
#ifndef __cplusplus
32
 
#  include <stdbool.h>
33
 
#endif
34
31
 
35
32
#include "macros.h"
36
33
 
 
34
#include <memory>
 
35
#include <utility>
 
36
#include <type_traits>
 
37
#include <initializer_list>
 
38
 
37
39
/**
38
40
 * \file utils.h
39
41
 * \author Yichao Yu <yyc1992@gmail.com>
58
60
}
59
61
 
60
62
/**
61
 
 * Free a pointer if it is not NULL.
62
 
 * \param p the pointer to be freed.
63
 
 */
64
 
QTC_ALWAYS_INLINE static inline void
65
 
qtcFree(void *p)
66
 
{
67
 
    if (p) {
68
 
        free(p);
69
 
    }
70
 
}
71
 
 
72
 
/**
73
63
 * Allocate memory of size \param size for a \param type.
74
64
 * The memory is initialized to zero.
75
65
 * \param type type pointed to by the pointer
88
78
#define qtcNew(type, n...)                              \
89
79
    qtcNewSize(type, sizeof(type) * (QTC_DEFAULT(n, 1)))
90
80
 
91
 
#ifdef __cplusplus
92
81
namespace QtCurve {
 
82
 
 
83
template<typename T>
 
84
using remove_cvr_t = typename std::remove_cv<
 
85
    typename std::remove_reference<T>::type>::type;
 
86
 
 
87
template<typename T>
 
88
struct _isChar : std::is_same<remove_cvr_t<T>, char> {};
 
89
 
 
90
template<typename T>
 
91
struct _isCharPtr : std::integral_constant<
 
92
    bool,
 
93
    std::is_pointer<remove_cvr_t<T> >::value &&
 
94
    _isChar<typename std::remove_pointer<remove_cvr_t<T> >::type>::value> {};
 
95
 
 
96
template<typename T>
 
97
struct _isCharAry : std::integral_constant<
 
98
    bool,
 
99
    std::is_array<remove_cvr_t<T> >::value &&
 
100
    _isChar<typename std::remove_extent<remove_cvr_t<T> >::type>::value> {};
 
101
 
 
102
template<typename T>
 
103
struct _isCharStr : std::integral_constant<
 
104
    bool, _isCharPtr<T>::value || _isCharAry<T>::value> {};
 
105
 
 
106
template<typename T1, typename T2, class=void>
 
107
struct _oneOfCmp {
 
108
    inline bool operator()(T1 &&v1, T2 &&v2)
 
109
    {
 
110
        return std::forward<T1>(v1) == std::forward<T2>(v2);
 
111
    }
 
112
};
 
113
 
 
114
template<typename T1, typename T2>
 
115
struct _oneOfCmp<T1, T2, typename std::enable_if<_isCharStr<T1>::value &&
 
116
                                      _isCharStr<T2>::value>::type> {
 
117
    inline bool operator()(T1 &&v1, T2 &&v2)
 
118
    {
 
119
        return v1 && strcmp(v1, v2) == 0;
 
120
    }
 
121
};
 
122
 
 
123
template<typename...>
 
124
struct CaseCmp {
 
125
    inline bool operator()(const char *str1, const char *str2)
 
126
    {
 
127
        return str1 && strcasecmp(str1, str2) == 0;
 
128
    }
 
129
};
 
130
 
 
131
template<template<typename...> class _Cmp=_oneOfCmp,
 
132
         typename T1, typename T2>
 
133
static inline bool
 
134
oneOf(T1 &&v1, T2 &&v2)
 
135
{
 
136
    return _Cmp<T1, T2>()(std::forward<T1>(v1), std::forward<T2>(v2));
 
137
}
 
138
 
 
139
template<template<typename...> class _Cmp=_oneOfCmp,
 
140
         typename T, typename First, typename... Rest>
 
141
static inline bool
 
142
oneOf(T &&value, First &&first, Rest&&... rest)
 
143
{
 
144
    return (oneOf<_Cmp>(std::forward<T>(value), std::forward<First>(first)) ||
 
145
            oneOf<_Cmp>(std::forward<T>(value), std::forward<Rest>(rest)...));
 
146
}
 
147
 
 
148
template<template<typename...> class _Cmp=_oneOfCmp,
 
149
         typename... Args>
 
150
static inline bool
 
151
noneOf(Args&&... args)
 
152
{
 
153
    return !oneOf<_Cmp>(std::forward<Args>(args)...);
 
154
}
 
155
 
93
156
/**
94
157
 * Turn a variable into a const reference. This is useful for range-based for
95
158
 * loop where a non-const variable may cause unnecessary copy.
100
163
{
101
164
    return t;
102
165
}
103
 
}
104
 
#endif
105
 
 
106
 
/**
107
 
 * Define a buffer type (struct) for \param type.
108
 
 * \sa QTC_DEF_LOCAL_BUFF
109
 
 */
110
 
#define QTC_BUFF_TYPE(type)                     \
111
 
    struct {                                    \
112
 
        union {                                 \
113
 
            type *p;                            \
114
 
            void *_p;                           \
115
 
        };                                      \
116
 
        size_t l;                               \
117
 
        type *const static_p;                   \
118
 
        const size_t static_l;                  \
119
 
    }
120
 
 
121
 
/**
122
 
 * \brief Define a local buffer for holding an array of \param type.
123
 
 * \param type type of the array element.
124
 
 * \param name name of the variable
125
 
 * \param stack_size the maximum number of elements in the array that will be
126
 
 *                   kept on the stack.
127
 
 * \param size real size of the array.
128
 
 *
129
 
 * This macro define a buffer \param name for an array of \param type.
130
 
 * The buffer's field p points to the address of the array.
131
 
 * Use QTC_FREE_LOCAL_BUFF to free the buffer.
132
 
 * \sa QTC_FREE_LOCAL_BUFF
133
 
 * \sa QTC_RESIZE_LOCAL_BUFF
134
 
 */
135
 
#define QTC_DEF_LOCAL_BUFF(type, name, stack_size, size)                \
136
 
    type __##qtc_local_buff##name[stack_size];                          \
137
 
    QTC_BUFF_TYPE(type) name = {                                        \
138
 
        {__##qtc_local_buff##name},                                     \
139
 
        sizeof(__##qtc_local_buff##name) / sizeof(type),                \
140
 
        __##qtc_local_buff##name,                                       \
141
 
        sizeof(__##qtc_local_buff##name) / sizeof(type)                 \
142
 
    };                                                                  \
143
 
    QTC_RESIZE_LOCAL_BUFF(name, size)
144
 
 
145
 
/**
146
 
 * \brief Resize a local buffer defined with QTC_DEF_LOCAL_BUFF for holding
147
 
 * .      more elements.
148
 
 * \param name name of the buffer
149
 
 * \param size new minimum size of the array.
150
 
 *
151
 
 * This macro resizes a buffer \param name defined with QTC_DEF_LOCAL_BUFF for
152
 
 * holding at least \param size elements.
153
 
 * \sa QTC_DEF_LOCAL_BUFF
154
 
 * \sa QTC_FREE_LOCAL_BUFF
155
 
 */
156
 
#define QTC_RESIZE_LOCAL_BUFF(name, size) do {                          \
157
 
        size_t __new_size = (size);                                     \
158
 
        if (__new_size <= (name).l || __new_size <= (name).static_l)    \
159
 
            break;                                                      \
160
 
        (name).l = __new_size;                                          \
161
 
        size_t __alloc_size = sizeof(*(name).p) * __new_size;           \
162
 
        if ((name).p == (name).static_p) {                              \
163
 
            (name)._p = malloc(__alloc_size);                           \
164
 
        } else {                                                        \
165
 
            (name)._p = realloc((name)._p, __alloc_size);               \
166
 
        }                                                               \
167
 
    } while (0)
168
 
 
169
 
/**
170
 
 * \brief Free a local buffer defined with QTC_DEF_LOCAL_BUFF if necessary.
171
 
 * \param name name of the buffer
172
 
 *
173
 
 * \sa QTC_DEF_LOCAL_BUFF
174
 
 * \sa QTC_RESIZE_LOCAL_BUFF
175
 
 */
176
 
#define QTC_FREE_LOCAL_BUFF(name) do {          \
177
 
        if ((name).p != (name).static_p) {      \
178
 
            free((name)._p);                    \
179
 
        }                                       \
180
 
    } while (0)
181
 
 
182
 
QTC_BEGIN_DECLS
183
 
 
184
 
/**
185
 
 * Binary searches an sorted array of \param nmemb objects.
186
 
 * \param key The key for the search.
187
 
 * \param base pointer to the first element.
188
 
 * \param nmemb number of object in the array.
189
 
 * \param size size of each object.
190
 
 * \param compar function to compare key with an object.
191
 
 *
192
 
 * \return if a matching object is found, the pointer to the object will be
193
 
 *         returned, otherwise, a pointer to where the new object should be
194
 
 *         inserted will be returned. If the key is greater than all the
195
 
 *         elements in the array, the returned pointer will point to the end
196
 
 *         of the list, i.e. out of the bound of the list.
197
 
 */
198
 
void *qtcBSearch(const void *key, const void *base, size_t nmemb, size_t size,
199
 
                 int (*compar)(const void*, const void*));
200
 
const char *qtcGetProgName();
201
 
 
202
 
QTC_END_DECLS
203
 
 
204
 
#ifdef __cplusplus
205
 
#include <utility>
206
 
template<typename T, typename First>
207
 
QTC_ALWAYS_INLINE static inline bool
208
 
qtcOneOf(T &&value, First &&first)
209
 
{
210
 
    return value == first;
211
 
}
212
 
template<typename T, typename First, typename... Rest>
213
 
QTC_ALWAYS_INLINE static inline bool
214
 
qtcOneOf(T &&value, First &&first, Rest &&...rest...)
215
 
{
216
 
    return value == first || qtcOneOf(std::forward<T>(value),
217
 
                                      std::forward<Rest>(rest)...);
218
 
}
 
166
 
 
167
struct CDeleter {
 
168
    template<typename T>
 
169
    void operator()(T *p)
 
170
    {
 
171
        free((void*)p);
 
172
    }
 
173
};
 
174
 
 
175
template<typename T>
 
176
using uniqueCPtr = std::unique_ptr<T, CDeleter>;
 
177
 
 
178
template<typename T, size_t N>
 
179
class LocalBuff {
 
180
    LocalBuff(const LocalBuff&) = delete;
 
181
public:
 
182
    LocalBuff(size_t size=N, const T *ary=nullptr)
 
183
        : m_ptr(size > N ? qtcNew(T, size) : m_static_buf),
 
184
          m_size(size),
 
185
          m_static_buf{}
 
186
    {
 
187
        if (ary) {
 
188
            memcpy(m_ptr, ary, sizeof(T) * size);
 
189
        }
 
190
    }
 
191
    bool
 
192
    is_static() const
 
193
    {
 
194
        return m_ptr == m_static_buf;
 
195
    }
 
196
    void
 
197
    resize(size_t size)
 
198
    {
 
199
        if (is_static()) {
 
200
            if (size > N) {
 
201
                m_ptr = qtcNew(T, size);
 
202
                memcpy(m_ptr, m_static_buf, sizeof(T) * m_size);
 
203
            }
 
204
        } else {
 
205
            m_ptr = (T*)realloc(m_ptr, sizeof(T) * size);
 
206
        }
 
207
        m_size = size;
 
208
    }
 
209
    T*
 
210
    get() const
 
211
    {
 
212
        return m_ptr;
 
213
    }
 
214
    T&
 
215
    operator[](size_t i) const
 
216
    {
 
217
        return get()[i];
 
218
    }
 
219
    size_t
 
220
    size() const
 
221
    {
 
222
        return m_size;
 
223
    }
 
224
    ~LocalBuff()
 
225
    {
 
226
        if (!is_static()) {
 
227
            free(m_ptr);
 
228
        }
 
229
    }
 
230
protected:
 
231
    T *m_ptr;
 
232
    size_t m_size;
 
233
private:
 
234
    T m_static_buf[N];
 
235
};
 
236
 
 
237
const char *getProgName();
 
238
}
 
239
 
 
240
extern "C" const char *qtcVersion();
 
241
 
 
242
template<typename T>
 
243
using qtcPtrType = QtCurve::remove_cvr_t<typename std::remove_pointer<T>::type>;
 
244
 
 
245
#define qtcMemPtr(ptr, name) &qtcPtrType<decltype(ptr)>::name
 
246
 
219
247
// Use lambda for lazy evaluation of \param def
220
 
#define qtcDefault(val, def)                    \
221
 
    (([&]() {                                   \
 
248
#define qtcDefault(val, def) ([&] {             \
222
249
            auto __val = (val);                 \
223
250
            return __val ? __val : (def);       \
224
 
        })())
 
251
        }())
225
252
// Use lambda for lazy evaluation of \param args
226
253
// C++ allows returning void expression! =) See the quote of the standard
227
254
// (here)[http://gcc.gnu.org/ml/gcc/2006-10/msg00697.html]
228
255
// The current c++ implementation of this macro does not support functions
229
256
// with types that do not have accessible default constructor (including
230
257
// references) as return type.
231
 
#define qtcCall(func, args...)                                          \
232
 
    (([&]() {                                                           \
 
258
#define qtcCall(func, args...) ([&] {                                   \
233
259
            auto __func = (func);                                       \
234
260
            return __func ? __func(args) : decltype(__func(args))();    \
235
 
        })())
 
261
        }())
236
262
#define qtcAssign(addr, exp) do {               \
237
263
        auto __addr = (addr);                   \
238
264
        if (__addr) {                           \
239
265
            *__addr = (exp);                    \
240
266
        }                                       \
241
267
    } while(0)
242
 
#else
243
 
#define qtcOneOf(exp, args...)                                  \
244
 
    ({                                                          \
245
 
        const typeof((exp)) __val = (exp);                      \
246
 
        const typeof((exp)) __args[] = {args};                  \
247
 
        size_t __arg_n = sizeof(__args) / sizeof(__args[0]);    \
248
 
        bool __res = false;                                     \
249
 
        for (size_t __i = 0;__i < __arg_n;__i++) {              \
250
 
            if (__val == __args[__i]) {                         \
251
 
                __res = true;                                   \
252
 
                break;                                          \
253
 
            }                                                   \
254
 
        }                                                       \
255
 
        __res;                                                  \
256
 
    })
257
 
#define qtcDefault(val, def)                    \
258
 
    ({                                          \
259
 
        typeof(val) __val = (val);              \
260
 
        __val ? __val : (def);                  \
261
 
    })
262
 
// The current c implementation of this macro does not support functions
263
 
// with non-scaler as return type.
264
 
#define qtcCall(func, args...)                                  \
265
 
    ({                                                          \
266
 
        typeof(func) __func = (func);                           \
267
 
        __func ? __func(args) : (typeof(__func(args)))0;        \
268
 
    })
269
 
#define qtcAssign(addr, exp) do {               \
270
 
        typeof(addr) __addr = (addr);           \
271
 
        if (__addr) {                           \
272
 
            *__addr = (exp);                    \
273
 
        }                                       \
274
 
    } while(0)
275
 
#endif
276
 
#define qtcNoneOf(args...) (!qtcOneOf(args))
277
268
 
278
 
// gcc and clang both seem find with returning void expression in c
279
 
// (even with -ansi).
280
 
// Not sure if this is standard but should be fine since we require gnu99
281
 
// anyway.
 
269
// Returning a void expression is valid c++, see above
 
270
// Or https://gcc.gnu.org/ml/gcc/2006-10/msg00697.html
282
271
#define QTC_RET_IF_FAIL(exp, val...) do {       \
283
272
        if (!qtcLikely(exp)) {                  \
284
273
            return (QTC_DEFAULT(val, (void)0)); \