Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /* Internal stuff needed by TypedEnum.h and TypedEnumBits.h. */ |
michael@0 | 8 | |
michael@0 | 9 | // NOTE: When we can assume C++11 enum class support and TypedEnum.h goes away, |
michael@0 | 10 | // we should then consider folding TypedEnumInternal.h into TypedEnumBits.h. |
michael@0 | 11 | |
michael@0 | 12 | #ifndef mozilla_TypedEnumInternal_h |
michael@0 | 13 | #define mozilla_TypedEnumInternal_h |
michael@0 | 14 | |
michael@0 | 15 | #include "mozilla/Attributes.h" |
michael@0 | 16 | |
michael@0 | 17 | #if defined(__cplusplus) |
michael@0 | 18 | |
michael@0 | 19 | #if defined(__clang__) |
michael@0 | 20 | /* |
michael@0 | 21 | * Per Clang documentation, "Note that marketing version numbers should not |
michael@0 | 22 | * be used to check for language features, as different vendors use different |
michael@0 | 23 | * numbering schemes. Instead, use the feature checking macros." |
michael@0 | 24 | */ |
michael@0 | 25 | # ifndef __has_extension |
michael@0 | 26 | # define __has_extension __has_feature /* compatibility, for older versions of clang */ |
michael@0 | 27 | # endif |
michael@0 | 28 | # if __has_extension(cxx_strong_enums) |
michael@0 | 29 | # define MOZ_HAVE_CXX11_ENUM_TYPE |
michael@0 | 30 | # define MOZ_HAVE_CXX11_STRONG_ENUMS |
michael@0 | 31 | # endif |
michael@0 | 32 | #elif defined(__GNUC__) |
michael@0 | 33 | # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L |
michael@0 | 34 | # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3) |
michael@0 | 35 | # define MOZ_HAVE_CXX11_ENUM_TYPE |
michael@0 | 36 | # define MOZ_HAVE_CXX11_STRONG_ENUMS |
michael@0 | 37 | # endif |
michael@0 | 38 | # endif |
michael@0 | 39 | #elif defined(_MSC_VER) |
michael@0 | 40 | # if _MSC_VER >= 1400 |
michael@0 | 41 | # define MOZ_HAVE_CXX11_ENUM_TYPE |
michael@0 | 42 | # endif |
michael@0 | 43 | # if _MSC_VER >= 1700 |
michael@0 | 44 | # define MOZ_HAVE_CXX11_STRONG_ENUMS |
michael@0 | 45 | # endif |
michael@0 | 46 | #endif |
michael@0 | 47 | |
michael@0 | 48 | namespace mozilla { |
michael@0 | 49 | |
michael@0 | 50 | /* |
michael@0 | 51 | * The problem that CastableTypedEnumResult aims to solve is that |
michael@0 | 52 | * typed enums are not convertible to bool, and there is no way to make them |
michael@0 | 53 | * be, yet user code wants to be able to write |
michael@0 | 54 | * |
michael@0 | 55 | * if (myFlags & Flags::SOME_PARTICULAR_FLAG) (1) |
michael@0 | 56 | * |
michael@0 | 57 | * There are different approaches to solving this. Most of them require |
michael@0 | 58 | * adapting user code. For example, we could implement operator! and have |
michael@0 | 59 | * the user write |
michael@0 | 60 | * |
michael@0 | 61 | * if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG)) (2) |
michael@0 | 62 | * |
michael@0 | 63 | * Or we could supply a IsNonZero() or Any() function returning whether |
michael@0 | 64 | * an enum value is nonzero, and have the user write |
michael@0 | 65 | * |
michael@0 | 66 | * if (Any(Flags & Flags::SOME_PARTICULAR_FLAG)) (3) |
michael@0 | 67 | * |
michael@0 | 68 | * But instead, we choose to preserve the original user syntax (1) as it |
michael@0 | 69 | * is inherently more readable, and to ease porting existing code to typed |
michael@0 | 70 | * enums. We achieve this by having operator& and other binary bitwise |
michael@0 | 71 | * operators have as return type a class, CastableTypedEnumResult, |
michael@0 | 72 | * that wraps a typed enum but adds bool convertibility. |
michael@0 | 73 | */ |
michael@0 | 74 | template<typename E> |
michael@0 | 75 | class CastableTypedEnumResult |
michael@0 | 76 | { |
michael@0 | 77 | private: |
michael@0 | 78 | const E mValue; |
michael@0 | 79 | |
michael@0 | 80 | public: |
michael@0 | 81 | explicit MOZ_CONSTEXPR CastableTypedEnumResult(E value) |
michael@0 | 82 | : mValue(value) |
michael@0 | 83 | {} |
michael@0 | 84 | |
michael@0 | 85 | MOZ_CONSTEXPR operator E() const { return mValue; } |
michael@0 | 86 | |
michael@0 | 87 | template<typename DestinationType> |
michael@0 | 88 | MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR |
michael@0 | 89 | operator DestinationType() const { |
michael@0 | 90 | return DestinationType(mValue); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); } |
michael@0 | 94 | |
michael@0 | 95 | #ifndef MOZ_HAVE_CXX11_STRONG_ENUMS |
michael@0 | 96 | // This get() method is used to implement a constructor in the |
michael@0 | 97 | // non-c++11 fallback path for MOZ_BEGIN_ENUM_CLASS, taking a |
michael@0 | 98 | // CastableTypedEnumResult. If we try to implement it using the |
michael@0 | 99 | // above conversion operator E(), then at least clang 3.3 |
michael@0 | 100 | // (when forced to take the non-c++11 fallback path) compiles |
michael@0 | 101 | // this constructor to an infinite recursion. So we introduce this |
michael@0 | 102 | // get() method, that does exactly the same as the conversion operator, |
michael@0 | 103 | // to work around this. |
michael@0 | 104 | MOZ_CONSTEXPR E get() const { return mValue; } |
michael@0 | 105 | #endif |
michael@0 | 106 | }; |
michael@0 | 107 | |
michael@0 | 108 | } // namespace mozilla |
michael@0 | 109 | |
michael@0 | 110 | #endif // __cplusplus |
michael@0 | 111 | |
michael@0 | 112 | #endif // mozilla_TypedEnumInternal_h |