Bug 1776680 [wpt PR 34603] - [@container] Test invalidation of font-relative units...
[gecko.git] / dom / smil / SMILValue.cpp
blob4942e3b8b69cbdd38436673c63356c279633f06d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SMILValue.h"
9 #include "nsDebug.h"
10 #include <string.h>
12 namespace mozilla {
14 //----------------------------------------------------------------------
15 // Public methods
17 SMILValue::SMILValue(const SMILType* aType) : mType(SMILNullType::Singleton()) {
18 mU.mBool = false;
19 if (!aType) {
20 NS_ERROR("Trying to construct SMILValue with null mType pointer");
21 return;
24 InitAndCheckPostcondition(aType);
27 SMILValue::SMILValue(const SMILValue& aVal) : mType(SMILNullType::Singleton()) {
28 InitAndCheckPostcondition(aVal.mType);
29 mType->Assign(*this, aVal);
32 const SMILValue& SMILValue::operator=(const SMILValue& aVal) {
33 if (&aVal == this) return *this;
35 if (mType != aVal.mType) {
36 DestroyAndReinit(aVal.mType);
39 mType->Assign(*this, aVal);
41 return *this;
44 // Move constructor / reassignment operator:
45 SMILValue::SMILValue(SMILValue&& aVal) noexcept
46 : mU(aVal.mU), // Copying union is only OK because we clear aVal.mType
47 // below.
48 mType(aVal.mType) {
49 // Leave aVal with a null type, so that it's safely destructible (and won't
50 // mess with anything referenced by its union, which we've copied).
51 aVal.mType = SMILNullType::Singleton();
54 SMILValue& SMILValue::operator=(SMILValue&& aVal) noexcept {
55 if (!IsNull()) {
56 // Clean up any data we're currently tracking.
57 DestroyAndCheckPostcondition();
60 // Copy the union (which could include a pointer to external memory) & mType:
61 mU = aVal.mU;
62 mType = aVal.mType;
64 // Leave aVal with a null type, so that it's safely destructible (and won't
65 // mess with anything referenced by its union, which we've now copied).
66 aVal.mType = SMILNullType::Singleton();
68 return *this;
71 bool SMILValue::operator==(const SMILValue& aVal) const {
72 if (&aVal == this) return true;
74 return mType == aVal.mType && mType->IsEqual(*this, aVal);
77 nsresult SMILValue::Add(const SMILValue& aValueToAdd, uint32_t aCount) {
78 if (aValueToAdd.mType != mType) {
79 NS_ERROR("Trying to add incompatible types");
80 return NS_ERROR_FAILURE;
83 return mType->Add(*this, aValueToAdd, aCount);
86 nsresult SMILValue::SandwichAdd(const SMILValue& aValueToAdd) {
87 if (aValueToAdd.mType != mType) {
88 NS_ERROR("Trying to add incompatible types");
89 return NS_ERROR_FAILURE;
92 return mType->SandwichAdd(*this, aValueToAdd);
95 nsresult SMILValue::ComputeDistance(const SMILValue& aTo,
96 double& aDistance) const {
97 if (aTo.mType != mType) {
98 NS_ERROR("Trying to calculate distance between incompatible types");
99 return NS_ERROR_FAILURE;
102 return mType->ComputeDistance(*this, aTo, aDistance);
105 nsresult SMILValue::Interpolate(const SMILValue& aEndVal, double aUnitDistance,
106 SMILValue& aResult) const {
107 if (aEndVal.mType != mType) {
108 NS_ERROR("Trying to interpolate between incompatible types");
109 return NS_ERROR_FAILURE;
112 if (aResult.mType != mType) {
113 // Outparam has wrong type
114 aResult.DestroyAndReinit(mType);
117 return mType->Interpolate(*this, aEndVal, aUnitDistance, aResult);
120 //----------------------------------------------------------------------
121 // Helper methods
123 // Wrappers for SMILType::Init & ::Destroy that verify their postconditions
124 void SMILValue::InitAndCheckPostcondition(const SMILType* aNewType) {
125 aNewType->Init(*this);
126 MOZ_ASSERT(mType == aNewType,
127 "Post-condition of Init failed. SMILValue is invalid");
130 void SMILValue::DestroyAndCheckPostcondition() {
131 mType->Destroy(*this);
132 MOZ_ASSERT(IsNull(),
133 "Post-condition of Destroy failed. "
134 "SMILValue not null after destroying");
137 void SMILValue::DestroyAndReinit(const SMILType* aNewType) {
138 DestroyAndCheckPostcondition();
139 InitAndCheckPostcondition(aNewType);
142 } // namespace mozilla