Noel Grandin 08489c211a almost nobody is using the oox::AttributeList::get methods properly
Most of the call sites just ignore the fact that we are returning an
optional value here.
Which means that when an attribute is missing, they get an empty string
or zero.
And we seem to be fine with that.

So make a plugin that warns about calling value() on a temporay OptValue.

And add a utility method so we don't have to pay the cost of passing
a default value to getString()

The need for this is driven by wanting to change to std::optional, which
will throw an exception if code attempts to read an empty std::optional

Change-Id: Idb0a5ad1eac66b5caa93d6195928bad9e0b2ad70
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136283
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2022-06-24 10:40:19 +02:00

76 lines
1.8 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* 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/.
*/
#include "config_clang.h"
template <typename Type> class OptValue
{
public:
OptValue()
: maValue()
, mbHasValue(false)
{
}
explicit OptValue(const Type& rValue)
: maValue(rValue)
, mbHasValue(true)
{
}
bool has_value() const { return mbHasValue; }
bool operator!() const { return !mbHasValue; }
const Type& value() const { return maValue; }
const Type& value_or(const Type& rDefValue) const { return mbHasValue ? maValue : rDefValue; }
Type& operator*() { return maValue; }
Type& emplace()
{
mbHasValue = true;
maValue = Type();
return maValue;
}
OptValue& operator=(const Type& rValue)
{
maValue = rValue;
mbHasValue = true;
return *this;
}
bool operator==(const OptValue& rValue) const
{
return ((!mbHasValue && rValue.mbHasValue == false)
|| (mbHasValue == rValue.mbHasValue && maValue == rValue.maValue));
}
private:
Type maValue;
bool mbHasValue;
};
struct AttributeList
{
OptValue<int> getInteger();
};
namespace test1
{
void foo(AttributeList& rAttrs)
{
// expected-error@+1 {{call to OptValue::value() [loplugin:optvalue]}}
rAttrs.getInteger().value();
// no warning expected
OptValue<int> x;
x.value();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */