blob: 1dd672bea479e18ca7767c90558a13b2683edf59 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkTypes_DEFINED
9#define SkTypes_DEFINED
10
bungemanf20488b2015-07-29 11:49:40 -070011// IWYU pragma: begin_exports
bsalomonf48c62f2016-07-08 03:28:42 -070012
13// In at least two known scenarios when using GCC with libc++:
14// * GCC 4.8 targeting ARMv7 with NEON
15// * GCC 4.9 targeting ARMv8 64 bit
16// we need to typedef float float32_t (or include <arm_neon.h> which does that)
17// before #including <memory>. This makes no sense. I'm not very interested in
18// understanding why... these are old, bizarre platform configuration that we
19// should just let die.
bungeman7ad42cf2016-07-08 12:25:37 -070020// See https://llvm.org/bugs/show_bug.cgi?id=25608 .
bsalomonf48c62f2016-07-08 03:28:42 -070021#include <ciso646> // Include something innocuous to define _LIBCPP_VERISON if it's libc++.
22#if defined(__GNUC__) && __GNUC__ == 4 \
bungeman7ad42cf2016-07-08 12:25:37 -070023 && ((defined(__arm__) && (defined(__ARM_NEON__) || defined(__ARM_NEON))) || defined(__aarch64__)) \
bsalomonf48c62f2016-07-08 03:28:42 -070024 && defined(_LIBCPP_VERSION)
25 typedef float float32_t;
26 #include <memory>
27#endif
28
reed@android.com8a1c16f2008-12-17 15:59:43 +000029#include "SkPreConfig.h"
30#include "SkUserConfig.h"
31#include "SkPostConfig.h"
bungemanf20488b2015-07-29 11:49:40 -070032#include <stddef.h>
bungeman@google.comfab44db2013-10-11 18:50:45 +000033#include <stdint.h>
bungemanf20488b2015-07-29 11:49:40 -070034// IWYU pragma: end_exports
35
bungemanf20488b2015-07-29 11:49:40 -070036#include <string.h>
Herb Derbyd7b34a52017-03-20 11:19:23 -040037// TODO(herb): remove after chromuim skia/ext/SkMemory_new_handler.cpp
Herb Derbyb549cc32017-03-27 13:35:15 -040038// has been updated to point to private/SkMalloc.h
39#include "../private/SkMalloc.h"
mtklein95cc0122015-04-27 15:11:01 -070040
Mike Reedea5e6762017-03-02 20:22:35 +000041// enable to test new device-base clipping
42//#define SK_USE_DEVICE_CLIPPING
43
reed@android.com8a1c16f2008-12-17 15:59:43 +000044/** \file SkTypes.h
45*/
46
reed@android.com9aa8b322010-04-13 13:22:54 +000047/** See SkGraphics::GetVersion() to retrieve these at runtime
48 */
49#define SKIA_VERSION_MAJOR 1
50#define SKIA_VERSION_MINOR 0
51#define SKIA_VERSION_PATCH 0
52
reed@android.com8a1c16f2008-12-17 15:59:43 +000053
reed@android.com8a1c16f2008-12-17 15:59:43 +000054/** Called internally if we hit an unrecoverable error.
55 The platform implementation must not return, but should either throw
56 an exception or otherwise exit.
57*/
djsollenf2b340f2016-01-29 08:51:04 -080058SK_API extern void sk_abort_no_print(void);
reed@android.com8a1c16f2008-12-17 15:59:43 +000059
reed@google.combdf73612011-09-06 14:56:20 +000060///////////////////////////////////////////////////////////////////////////////
61
mtklein36352bf2015-03-25 18:17:31 -070062#ifdef override_GLOBAL_NEW
reed@google.combdf73612011-09-06 14:56:20 +000063#include <new>
64
65inline void* operator new(size_t size) {
66 return sk_malloc_throw(size);
67}
68
69inline void operator delete(void* p) {
70 sk_free(p);
71}
72#endif
73
74///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000075
76#define SK_INIT_TO_AVOID_WARNING = 0
77
78#ifndef SkDebugf
georgec4ade572014-08-01 12:02:07 -070079 SK_API void SkDebugf(const char format[], ...);
reed@android.com8a1c16f2008-12-17 15:59:43 +000080#endif
81
caryclarkd6562002016-07-27 12:02:07 -070082#define SkREQUIRE_SEMICOLON_AFTER(code) do { code } while (false)
83
84#define SkASSERT_RELEASE(cond) \
85 SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT(#cond); } )
djsollenf2b340f2016-01-29 08:51:04 -080086
reed@android.com8a1c16f2008-12-17 15:59:43 +000087#ifdef SK_DEBUG
caryclarkd6562002016-07-27 12:02:07 -070088 #define SkASSERT(cond) \
89 SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT("assert(" #cond ")"); })
90 #define SkASSERTF(cond, fmt, ...) \
91 SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { \
92 SkDebugf(fmt"\n", __VA_ARGS__); \
93 SK_ABORT("assert(" #cond ")"); \
94 })
bungeman1f790aa2016-07-20 09:49:10 -070095 #define SkDEBUGFAIL(message) SK_ABORT(message)
herb966e3d32015-09-18 07:00:48 -070096 #define SkDEBUGFAILF(fmt, ...) SkASSERTF(false, fmt, ##__VA_ARGS__)
csmartdaltonceeaa782016-08-10 10:07:57 -070097 #define SkDEBUGCODE(...) __VA_ARGS__
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 #define SkDECLAREPARAM(type, var) , type var
99 #define SkPARAM(var) , var
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 #define SkDEBUGF(args ) SkDebugf args
101 #define SkAssertResult(cond) SkASSERT(cond)
102#else
103 #define SkASSERT(cond)
bungeman1f790aa2016-07-20 09:49:10 -0700104 #define SkASSERTF(cond, fmt, ...)
tomhudson@google.com0c00f212011-12-28 14:59:50 +0000105 #define SkDEBUGFAIL(message)
hsterne6f8ff02016-08-15 15:26:31 -0700106 #define SkDEBUGFAILF(fmt, ...)
csmartdaltonceeaa782016-08-10 10:07:57 -0700107 #define SkDEBUGCODE(...)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108 #define SkDEBUGF(args)
109 #define SkDECLAREPARAM(type, var)
110 #define SkPARAM(var)
111
bsalomon9daa4b92016-05-09 09:14:36 -0700112 // unlike SkASSERT, this guy executes its condition in the non-debug build.
bsalomon1b4c01c2016-05-09 12:35:17 -0700113 // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
114 #define SkAssertResult(cond) if (cond) {} do {} while(false)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115#endif
116
djsollenf2b340f2016-01-29 08:51:04 -0800117// Legacy macro names for SK_ABORT
118#define SkFAIL(message) SK_ABORT(message)
119#define sk_throw() SK_ABORT("sk_throw")
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000120
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000121#ifdef SK_IGNORE_TO_STRING
skia.committer@gmail.combc3d92a2014-03-14 03:02:26 +0000122 #define SK_TO_STRING_NONVIRT()
123 #define SK_TO_STRING_VIRT()
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000124 #define SK_TO_STRING_PUREVIRT()
125 #define SK_TO_STRING_OVERRIDE()
126#else
bungemand3ebb482015-08-05 13:57:49 -0700127 class SkString;
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000128 // the 'toString' helper functions convert Sk* objects to human-readable
129 // form in developer mode
130 #define SK_TO_STRING_NONVIRT() void toString(SkString* str) const;
131 #define SK_TO_STRING_VIRT() virtual void toString(SkString* str) const;
132 #define SK_TO_STRING_PUREVIRT() virtual void toString(SkString* str) const = 0;
mtklein36352bf2015-03-25 18:17:31 -0700133 #define SK_TO_STRING_OVERRIDE() void toString(SkString* str) const override;
robertphillips@google.com76f9e932013-01-15 20:17:47 +0000134#endif
135
reed@google.com49a5b192012-10-25 17:31:39 +0000136/*
137 * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab
138 *
139 * SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
140 *
141 */
142#define SK_MACRO_CONCAT(X, Y) SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
143#define SK_MACRO_CONCAT_IMPL_PRIV(X, Y) X ## Y
144
145/*
146 * Usage: SK_MACRO_APPEND_LINE(foo) to make foo123, where 123 is the current
147 * line number. Easy way to construct
148 * unique names for local functions or
149 * variables.
150 */
151#define SK_MACRO_APPEND_LINE(name) SK_MACRO_CONCAT(name, __LINE__)
152
commit-bot@chromium.orge61a86c2013-11-18 16:03:59 +0000153/**
154 * For some classes, it's almost always an error to instantiate one without a name, e.g.
155 * {
156 * SkAutoMutexAcquire(&mutex);
157 * <some code>
158 * }
159 * In this case, the writer meant to hold mutex while the rest of the code in the block runs,
160 * but instead the mutex is acquired and then immediately released. The correct usage is
161 * {
162 * SkAutoMutexAcquire lock(&mutex);
163 * <some code>
164 * }
165 *
166 * To prevent callers from instantiating your class without a name, use SK_REQUIRE_LOCAL_VAR
167 * like this:
168 * class classname {
169 * <your class>
170 * };
171 * #define classname(...) SK_REQUIRE_LOCAL_VAR(classname)
172 *
173 * This won't work with templates, and you must inline the class' constructors and destructors.
174 * Take a look at SkAutoFree and SkAutoMalloc in this file for examples.
175 */
176#define SK_REQUIRE_LOCAL_VAR(classname) \
bungeman99fe8222015-08-20 07:57:51 -0700177 static_assert(false, "missing name for " #classname)
commit-bot@chromium.orge61a86c2013-11-18 16:03:59 +0000178
reed@android.com8a1c16f2008-12-17 15:59:43 +0000179///////////////////////////////////////////////////////////////////////
180
reed@google.com37a31332011-01-25 14:55:42 +0000181/**
182 * Fast type for signed 8 bits. Use for parameter passing and local variables,
183 * not for storage.
184 */
185typedef int S8CPU;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186
reed@google.com37a31332011-01-25 14:55:42 +0000187/**
188 * Fast type for unsigned 8 bits. Use for parameter passing and local
189 * variables, not for storage
190 */
191typedef unsigned U8CPU;
192
193/**
194 * Fast type for signed 16 bits. Use for parameter passing and local variables,
195 * not for storage
196 */
197typedef int S16CPU;
198
199/**
200 * Fast type for unsigned 16 bits. Use for parameter passing and local
201 * variables, not for storage
202 */
203typedef unsigned U16CPU;
204
205/**
reed@google.com37a31332011-01-25 14:55:42 +0000206 * Meant to be a small version of bool, for storage purposes. Will be 0 or 1
207 */
208typedef uint8_t SkBool8;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000209
bungeman68c14d92016-03-19 15:06:56 -0700210#include "../private/SkTFitsIn.h"
211template <typename D, typename S> D SkTo(S s) {
212 SkASSERT(SkTFitsIn<D>(s));
213 return static_cast<D>(s);
214}
215#define SkToS8(x) SkTo<int8_t>(x)
216#define SkToU8(x) SkTo<uint8_t>(x)
217#define SkToS16(x) SkTo<int16_t>(x)
218#define SkToU16(x) SkTo<uint16_t>(x)
219#define SkToS32(x) SkTo<int32_t>(x)
220#define SkToU32(x) SkTo<uint32_t>(x)
221#define SkToInt(x) SkTo<int>(x)
222#define SkToUInt(x) SkTo<unsigned>(x)
223#define SkToSizeT(x) SkTo<size_t>(x)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000224
225/** Returns 0 or 1 based on the condition
226*/
mtklein5c05d102015-12-02 12:32:02 -0800227#define SkToBool(cond) ((cond) != 0)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000228
229#define SK_MaxS16 32767
230#define SK_MinS16 -32767
231#define SK_MaxU16 0xFFFF
232#define SK_MinU16 0
233#define SK_MaxS32 0x7FFFFFFF
caryclark@google.com594dd3c2012-09-24 19:33:57 +0000234#define SK_MinS32 -SK_MaxS32
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235#define SK_MaxU32 0xFFFFFFFF
236#define SK_MinU32 0
caryclark952538e2016-02-26 05:01:42 -0800237#define SK_NaN32 ((int) (1U << 31))
reed@android.com8a1c16f2008-12-17 15:59:43 +0000238
reed@android.comd4577752009-11-21 02:48:11 +0000239/** Returns true if the value can be represented with signed 16bits
240 */
reed@android.com90209ca2009-11-21 19:58:04 +0000241static inline bool SkIsS16(long x) {
reed@android.comd4577752009-11-21 02:48:11 +0000242 return (int16_t)x == x;
243}
244
245/** Returns true if the value can be represented with unsigned 16bits
246 */
reed@android.com90209ca2009-11-21 19:58:04 +0000247static inline bool SkIsU16(long x) {
reed@android.comd4577752009-11-21 02:48:11 +0000248 return (uint16_t)x == x;
249}
250
caryclark3127c992015-12-09 12:02:30 -0800251static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
252 return (int32_t) ((uint32_t) value << shift);
253}
254
255static inline int64_t SkLeftShift(int64_t value, int32_t shift) {
256 return (int64_t) ((uint64_t) value << shift);
257}
258
reed@android.comd4577752009-11-21 02:48:11 +0000259//////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000260
mtkleinfc00a7c2015-05-07 10:58:44 -0700261/** Returns the number of entries in an array (not a pointer) */
262template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
caryclark95b96d62015-08-19 10:12:59 -0700263#define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
reed@android.com8a1c16f2008-12-17 15:59:43 +0000264
mtkleinb68ce742015-11-24 05:35:58 -0800265// Can be used to bracket data types that must be dense, e.g. hash keys.
266#if defined(__clang__) // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
267 #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
268 _Pragma("GCC diagnostic error \"-Wpadded\"")
269 #define SK_END_REQUIRE_DENSE _Pragma("GCC diagnostic pop")
270#else
271 #define SK_BEGIN_REQUIRE_DENSE
272 #define SK_END_REQUIRE_DENSE
273#endif
274
mtklein6a259bf2016-09-26 18:20:57 -0700275#define SkAlign2(x) (((x) + 1) >> 1 << 1)
276#define SkIsAlign2(x) (0 == ((x) & 1))
reed@android.com8a1c16f2008-12-17 15:59:43 +0000277
mtklein6a259bf2016-09-26 18:20:57 -0700278#define SkAlign4(x) (((x) + 3) >> 2 << 2)
279#define SkIsAlign4(x) (0 == ((x) & 3))
reed@google.comc6faa5a2012-06-27 15:07:11 +0000280
mtklein6a259bf2016-09-26 18:20:57 -0700281#define SkAlign8(x) (((x) + 7) >> 3 << 3)
282#define SkIsAlign8(x) (0 == ((x) & 7))
tomhudson@google.com01224d52011-11-28 18:22:01 +0000283
mtklein6a259bf2016-09-26 18:20:57 -0700284#define SkAlign16(x) (((x) + 15) >> 4 << 4)
285#define SkIsAlign16(x) (0 == ((x) & 15))
reede2b0a0a2016-03-02 13:03:46 -0800286
mtklein6a259bf2016-09-26 18:20:57 -0700287#define SkAlignPtr(x) (sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x))
288#define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
mtklein0209e952014-08-28 14:10:05 -0700289
reed@android.com8a1c16f2008-12-17 15:59:43 +0000290typedef uint32_t SkFourByteTag;
291#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
292
293/** 32 bit integer to hold a unicode value
294*/
295typedef int32_t SkUnichar;
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700296
halcanaryd0e95a52016-07-25 07:18:12 -0700297/** 16 bit unsigned integer to hold a glyph index
298*/
299typedef uint16_t SkGlyphID;
300
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700301/** 32 bit value to hold a millisecond duration
302 * Note that SK_MSecMax is about 25 days.
303 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000304typedef uint32_t SkMSec;
305/** 1 second measured in milliseconds
306*/
307#define SK_MSec1 1000
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700308/** maximum representable milliseconds; 24d 20h 31m 23.647s.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000309*/
310#define SK_MSecMax 0x7FFFFFFF
311/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
312*/
313#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
314/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
315*/
316#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
317
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000318/** The generation IDs in Skia reserve 0 has an invalid marker.
319 */
320#define SK_InvalidGenID 0
bsalomon1c63bf62014-07-22 13:09:46 -0700321/** The unique IDs in Skia reserve 0 has an invalid marker.
322 */
323#define SK_InvalidUniqueID 0
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000324
reed@android.com8a1c16f2008-12-17 15:59:43 +0000325/****************************************************************************
326 The rest of these only build with C++
327*/
328#ifdef __cplusplus
329
330/** Faster than SkToBool for integral conditions. Returns 0 or 1
331*/
bsalomon7a5bcc52016-05-24 13:23:56 -0700332static inline constexpr int Sk32ToBool(uint32_t n) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333 return (n | (0-n)) >> 31;
334}
335
bsalomon@google.comff436612013-02-27 19:07:32 +0000336/** Generic swap function. Classes with efficient swaps should specialize this function to take
337 their fast path. This function is used by SkTSort. */
Mike Kleinbde64e42016-11-14 08:39:39 -0500338template <typename T> static inline void SkTSwap(T& a, T& b) {
bungeman6f4293a2016-10-26 12:11:28 -0700339 T c(std::move(a));
340 a = std::move(b);
341 b = std::move(c);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000342}
343
reed@android.comd4577752009-11-21 02:48:11 +0000344static inline int32_t SkAbs32(int32_t value) {
mtklein09a22e92014-11-21 11:38:53 -0800345 SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
commit-bot@chromium.org38bad322013-07-30 13:16:29 +0000346 if (value < 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000347 value = -value;
commit-bot@chromium.org38bad322013-07-30 13:16:29 +0000348 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000349 return value;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000350}
351
Mike Kleinbde64e42016-11-14 08:39:39 -0500352template <typename T> static inline T SkTAbs(T value) {
reed@google.com2b57dc62013-01-08 13:23:32 +0000353 if (value < 0) {
354 value = -value;
355 }
356 return value;
357}
358
reed@android.comd4577752009-11-21 02:48:11 +0000359static inline int32_t SkMax32(int32_t a, int32_t b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000360 if (a < b)
361 a = b;
362 return a;
363}
364
reed@android.comd4577752009-11-21 02:48:11 +0000365static inline int32_t SkMin32(int32_t a, int32_t b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000366 if (a > b)
367 a = b;
368 return a;
369}
370
halcanarya0af7712016-05-23 09:11:58 -0700371template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
caryclark@google.com3b97af52013-04-23 11:56:44 +0000372 return (a < b) ? a : b;
373}
374
halcanarya0af7712016-05-23 09:11:58 -0700375template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
caryclark@google.com3b97af52013-04-23 11:56:44 +0000376 return (b < a) ? a : b;
377}
378
reed@android.comd4577752009-11-21 02:48:11 +0000379static inline int32_t SkSign32(int32_t a) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000380 return (a >> 31) | ((unsigned) -a >> 31);
381}
382
reed@android.comd4577752009-11-21 02:48:11 +0000383static inline int32_t SkFastMin32(int32_t value, int32_t max) {
commit-bot@chromium.org38bad322013-07-30 13:16:29 +0000384 if (value > max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000385 value = max;
commit-bot@chromium.org38bad322013-07-30 13:16:29 +0000386 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000387 return value;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000388}
389
bungeman62ce0302015-08-28 09:09:32 -0700390/** Returns value pinned between min and max, inclusively. */
halcanarya0af7712016-05-23 09:11:58 -0700391template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
bungeman62ce0302015-08-28 09:09:32 -0700392 return SkTMax(SkTMin(value, max), min);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000393}
394
bsalomon5ec26ae2016-02-25 08:33:02 -0800395
396///////////////////////////////////////////////////////////////////////////////
397
398/**
399 * Indicates whether an allocation should count against a cache budget.
400 */
401enum class SkBudgeted : bool {
402 kNo = false,
403 kYes = true
404};
405
robertphillips76948d42016-05-04 12:47:41 -0700406/**
407 * Indicates whether a backing store needs to be an exact match or can be larger
408 * than is strictly necessary
409 */
410enum class SkBackingFit {
411 kApprox,
412 kExact
413};
414
reed@google.com1fcd51e2011-01-05 15:50:27 +0000415///////////////////////////////////////////////////////////////////////////////
416
vandebo@chromium.org325cb9a2011-03-30 18:36:29 +0000417/** Use to combine multiple bits in a bitmask in a type safe way.
418 */
419template <typename T>
420T SkTBitOr(T a, T b) {
421 return (T)(a | b);
422}
423
reed@google.com1fcd51e2011-01-05 15:50:27 +0000424/**
425 * Use to cast a pointer to a different type, and maintaining strict-aliasing
426 */
427template <typename Dst> Dst SkTCast(const void* ptr) {
428 union {
429 const void* src;
430 Dst dst;
431 } data;
432 data.src = ptr;
433 return data.dst;
434}
435
reed@android.com8a1c16f2008-12-17 15:59:43 +0000436//////////////////////////////////////////////////////////////////////////////
437
438/** \class SkNoncopyable
439
fmalita055f6b52015-04-09 08:49:32 -0700440SkNoncopyable is the base class for objects that do not want to
reed@android.com8a1c16f2008-12-17 15:59:43 +0000441be copied. It hides its copy-constructor and its assignment-operator.
442*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000443class SK_API SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000444public:
Chris Blume2b6be202017-04-25 17:33:13 -0700445 SkNoncopyable() = default;
reed@google.com1fcd51e2011-01-05 15:50:27 +0000446
Chris Blume2b6be202017-04-25 17:33:13 -0700447 SkNoncopyable(SkNoncopyable&&) = default;
448 SkNoncopyable& operator =(SkNoncopyable&&) = default;
449
450 SkNoncopyable(const SkNoncopyable&) = delete;
451 SkNoncopyable& operator=(const SkNoncopyable&) = delete;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000452};
453
reed@android.com8a1c16f2008-12-17 15:59:43 +0000454#endif /* C++ */
455
456#endif