summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2014-10-06 14:48:16 +0200
committerStephan Bergmann <sbergman@redhat.com>2014-10-13 17:45:57 +0200
commitaf5ebbf7835441c767f91a620f109ee6722e57bd (patch)
treec72b2a1ddb5aa0a0a369be7babd516a5592d5fac /include
parent1156d11ef0bb2bc3d71ae9299656db4fed66f073 (diff)
create a macro library for implementing bit-flags types
Signed-off-by: Stephan Bergmann <sbergman@redhat.com>, changed from a macro- to a template-based solution. (Unfortunately MSVC 2012 does not support explicit conversion operators. Worked around that with explicit #ifs rather than some HAVE_EXPLICIT_CONVERSION_OPERATORS and SAL_EXPLICIT_CONVERSION_OPERATOR ainticipating we hopefully soon move to a baseline that requires unconditional support for them.) Change-Id: I4a89643b218d247e8e4a861faba458ec6dfe1396
Diffstat (limited to 'include')
-rw-r--r--include/o3tl/typed_flags_set.hxx208
-rw-r--r--include/vcl/outdev.hxx2
-rw-r--r--include/vcl/outdevstate.hxx57
-rw-r--r--include/vcl/pdfwriter.hxx2
4 files changed, 238 insertions, 31 deletions
diff --git a/include/o3tl/typed_flags_set.hxx b/include/o3tl/typed_flags_set.hxx
new file mode 100644
index 000000000000..baa679354de5
--- /dev/null
+++ b/include/o3tl/typed_flags_set.hxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
+#define INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
+
+#include <sal/config.h>
+
+#include <cassert>
+#include <type_traits>
+
+namespace o3tl {
+
+template<typename T> struct typed_flags {};
+
+/// Mark a (scoped) enumeration as a set of bit flags, with accompanying
+/// operations.
+///
+/// template<>
+/// struct o3tl::typed_flags<TheE>: o3tl::is_typed_flags<TheE, TheM> {};
+///
+/// All relevant values must be non-negative. (Typically, the enumeration's
+/// underlying type will either be fixed and unsigned, or it will be unfixed---
+/// and can thus default to a signed type---and all enumerators will have non-
+/// negative values.)
+///
+/// \param E the enumeration type.
+/// \param M the all-bits-set value for the bit flags.
+template<typename E, typename std::underlying_type<E>::type M>
+struct is_typed_flags {
+ static_assert(
+ M >= 0, "is_typed_flags expects only non-negative bit values");
+
+ class Self {
+ public:
+ explicit Self(typename std::underlying_type<E>::type value):
+ value_(value)
+ { assert(value >= 0); }
+
+ operator E() { return static_cast<E>(value_); }
+
+#if !defined _MSC_VER || _MSC_VER > 1700
+ explicit
+#endif
+ operator typename std::underlying_type<E>::type() { return value_; }
+
+#if !defined _MSC_VER || _MSC_VER > 1700
+ explicit
+#endif
+ operator bool() { return value_ != 0; }
+
+ private:
+ typename std::underlying_type<E>::type value_;
+ };
+
+ static typename std::underlying_type<E>::type const mask = M;
+};
+
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator ~(E rhs) {
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ o3tl::typed_flags<E>::mask
+ & ~static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator ~(
+ typename o3tl::typed_flags<E>::Self rhs)
+{
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ o3tl::typed_flags<E>::mask
+ & ~static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &(E lhs, E rhs) {
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ & static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &(
+ E lhs, typename o3tl::typed_flags<E>::Self rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ & static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &(
+ typename o3tl::typed_flags<E>::Self lhs, E rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ & static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &(
+ typename o3tl::typed_flags<E>::Self lhs,
+ typename o3tl::typed_flags<E>::Self rhs)
+{
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ & static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |(E lhs, E rhs) {
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ | static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |(
+ E lhs, typename o3tl::typed_flags<E>::Self rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ | static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |(
+ typename o3tl::typed_flags<E>::Self lhs, E rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ | static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |(
+ typename o3tl::typed_flags<E>::Self lhs,
+ typename o3tl::typed_flags<E>::Self rhs)
+{
+ return static_cast<typename o3tl::typed_flags<E>::Self>(
+ static_cast<typename std::underlying_type<E>::type>(lhs)
+ | static_cast<typename std::underlying_type<E>::type>(rhs));
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &=(E & lhs, E rhs) {
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ lhs = lhs & rhs;
+ return lhs;
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator &=(
+ E & lhs, typename o3tl::typed_flags<E>::Self rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ lhs = lhs & rhs;
+ return lhs;
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |=(E & lhs, E rhs) {
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ assert(static_cast<typename std::underlying_type<E>::type>(rhs) >= 0);
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+template<typename E>
+inline typename o3tl::typed_flags<E>::Self operator |=(
+ E & lhs, typename o3tl::typed_flags<E>::Self rhs)
+{
+ assert(static_cast<typename std::underlying_type<E>::type>(lhs) >= 0);
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+#endif /* INCLUDED_O3TL_TYPED_FLAGS_SET_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index c90f09d8820c..d87100afe8f4 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -537,7 +537,7 @@ private:
public:
- void Push( PushFlags nFlags = PUSH_ALL );
+ void Push( PushFlags nFlags = PushFlags::ALL );
void Pop();
// returns the current stack depth; that is the number of Push() calls minus the number of Pop() calls
diff --git a/include/vcl/outdevstate.hxx b/include/vcl/outdevstate.hxx
index 9b2811a86a6a..da3dc4e0b050 100644
--- a/include/vcl/outdevstate.hxx
+++ b/include/vcl/outdevstate.hxx
@@ -30,38 +30,35 @@
#include <tools/gen.hxx>
#include <tools/color.hxx>
#include <tools/fontenum.hxx>
+#include <o3tl/typed_flags_set.hxx>
// Flags for OutputDevice::Push() and OutDevState
-enum PushFlags {
- PUSH_NONE = ((sal_uInt16)0x0000),
- PUSH_LINECOLOR = ((sal_uInt16)0x0001),
- PUSH_FILLCOLOR = ((sal_uInt16)0x0002),
- PUSH_FONT = ((sal_uInt16)0x0004),
- PUSH_TEXTCOLOR = ((sal_uInt16)0x0008),
- PUSH_MAPMODE = ((sal_uInt16)0x0010),
- PUSH_CLIPREGION = ((sal_uInt16)0x0020),
- PUSH_RASTEROP = ((sal_uInt16)0x0040),
- PUSH_TEXTFILLCOLOR = ((sal_uInt16)0x0080),
- PUSH_TEXTALIGN = ((sal_uInt16)0x0100),
- PUSH_REFPOINT = ((sal_uInt16)0x0200),
- PUSH_TEXTLINECOLOR = ((sal_uInt16)0x0400),
- PUSH_TEXTLAYOUTMODE = ((sal_uInt16)0x0800),
- PUSH_TEXTLANGUAGE = ((sal_uInt16)0x1000),
- PUSH_OVERLINECOLOR = ((sal_uInt16)0x2000),
- PUSH_ALL = ((sal_uInt16)0xFFFF)
+enum class PushFlags : sal_uInt16 {
+ NONE = 0x0000,
+ LINECOLOR = 0x0001,
+ FILLCOLOR = 0x0002,
+ FONT = 0x0004,
+ TEXTCOLOR = 0x0008,
+ MAPMODE = 0x0010,
+ CLIPREGION = 0x0020,
+ RASTEROP = 0x0040,
+ TEXTFILLCOLOR = 0x0080,
+ TEXTALIGN = 0x0100,
+ REFPOINT = 0x0200,
+ TEXTLINECOLOR = 0x0400,
+ TEXTLAYOUTMODE = 0x0800,
+ TEXTLANGUAGE = 0x1000,
+ OVERLINECOLOR = 0x2000,
+ ALL = 0xFFFF
+
+ //bool operator bool() { return static_cast<sal_uInt16>(*this) != 0; }
};
-// make combining these type-safe
-inline PushFlags operator| (PushFlags lhs, PushFlags rhs)
-{
- return static_cast<PushFlags>(static_cast<sal_uInt16>(lhs) | static_cast<sal_uInt16>(rhs));
-}
-inline PushFlags operator& (PushFlags lhs, PushFlags rhs)
-{
- return static_cast<PushFlags>(static_cast<sal_uInt16>(lhs) & static_cast<sal_uInt16>(rhs));
-}
+template<>
+struct o3tl::typed_flags<PushFlags>: o3tl::is_typed_flags<PushFlags, 0xFFFF> {};
+#define PUSH_ALLTEXT (PushFlags::TEXTCOLOR | PushFlags::TEXTFILLCOLOR | PushFlags::TEXTLINECOLOR | PushFlags::OVERLINECOLOR | PushFlags::TEXTALIGN | PushFlags::TEXTLAYOUTMODE | PushFlags::TEXTLANGUAGE)
+#define PUSH_ALLFONT (PUSH_ALLTEXT | PushFlags::FONT)
+
-#define PUSH_ALLTEXT (PUSH_TEXTCOLOR | PUSH_TEXTFILLCOLOR | PUSH_TEXTLINECOLOR | PUSH_OVERLINECOLOR | PUSH_TEXTALIGN | PUSH_TEXTLAYOUTMODE | PUSH_TEXTLANGUAGE)
-#define PUSH_ALLFONT (PUSH_ALLTEXT | PUSH_FONT)
// LayoutModes for Complex Text Layout
// These are flag values, i.e they can be combined
@@ -101,6 +98,8 @@ inline ComplexTextLayoutMode& operator&= (ComplexTextLayoutMode& lhs, ComplexTex
}
+
+
class OutDevState
{
public:
@@ -108,7 +107,7 @@ public:
MapMode* mpMapMode;
bool mbMapActive;
- vcl::Region* mpClipRegion;
+ vcl::Region* mpClipRegion;
Color* mpLineColor;
Color* mpFillColor;
vcl::Font* mpFont;
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 03211f42aa80..880e2fa30949 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -729,7 +729,7 @@ The following structure describes the permissions used in PDF security
/* functions for graphics state */
/* flag values: see vcl/outdev.hxx */
- void Push( PushFlags nFlags = PUSH_ALL );
+ void Push( PushFlags nFlags = PushFlags::ALL );
void Pop();
void SetClipRegion();