[niepce] base: add fwk::option<> and use it in PropertyBag
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] base: add fwk::option<> and use it in PropertyBag
- Date: Thu, 11 May 2017 02:06:27 +0000 (UTC)
commit d7ba6c44a80c338008f00e25d648430043d28ca4
Author: Hubert Figuière <hub figuiere net>
Date: Tue Mar 14 00:01:21 2017 -0400
base: add fwk::option<> and use it in PropertyBag
.gitignore | 1 +
src/fwk/base/Makefile.am | 9 +++-
src/fwk/base/option.hpp | 72 +++++++++++++++++++++++++++++++++
src/fwk/base/propertybag.cpp | 9 ++--
src/fwk/base/propertybag.hpp | 5 +-
src/fwk/base/t/testoption.cpp | 67 ++++++++++++++++++++++++++++++
src/fwk/toolkit/metadatawidget.cpp | 16 ++++----
src/niepce/modules/map/mapmodule.cpp | 11 +++--
src/niepce/ui/selectioncontroller.cpp | 15 ++++---
9 files changed, 178 insertions(+), 27 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 86cbb14..a525378 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@ src/fwk/base/testgeometry
src/fwk/base/testfractions
src/fwk/base/testdate
src/fwk/base/testmap
+src/fwk/base/testoption
src/fwk/base/testpropertybag
src/fwk/utils/test_db
src/fwk/utils/test_db2
diff --git a/src/fwk/base/Makefile.am b/src/fwk/base/Makefile.am
index 4015ac4..b855bfa 100644
--- a/src/fwk/base/Makefile.am
+++ b/src/fwk/base/Makefile.am
@@ -8,10 +8,10 @@ noinst_LIBRARIES = libfwkbase.a
TESTS = testmoniker testgeometry testfractions testdate testmap\
- testpropertybag
+ testoption testpropertybag
check_PROGRAMS = testmoniker testgeometry testfractions testdate testmap\
- testpropertybag
+ testoption testpropertybag
testdate_SOURCES = t/testdate.cpp
testdate_LDADD = libfwkbase.a \
@@ -33,6 +33,10 @@ testmap_SOURCES = t/testmap.cpp
testmap_LDADD = libfwkbase.a \
@FRAMEWORK_LIBS@
+testoption_SOURCES = t/testoption.cpp
+testoption_LDADD = libfwkbase.a \
+ @FRAMEWORK_LIBS@
+
testpropertybag_SOURCES = t/testpropertybag.cpp
testpropertybag_LDADD = libfwkbase.a \
@FRAMEWORK_LIBS@
@@ -47,5 +51,6 @@ libfwkbase_a_SOURCES = colour.hpp colour.cpp \
singleton.hpp \
util.hpp \
map.hpp \
+ option.hpp \
propertybag.hpp propertybag.cpp \
$(NULL)
diff --git a/src/fwk/base/option.hpp b/src/fwk/base/option.hpp
new file mode 100644
index 0000000..76df967
--- /dev/null
+++ b/src/fwk/base/option.hpp
@@ -0,0 +1,72 @@
+/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode:nil; -*- */
+/*
+ * niepce - fwk/base/option.hpp
+ *
+ * Copyright (C) 2017 Hubert Figuière
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// an option<> template class inspired by Rust
+
+#pragma once
+
+#include <stdexcept>
+
+namespace fwk {
+
+template<class T>
+class Option
+{
+public:
+ typedef T data_type;
+
+ Option()
+ : m_none(true)
+ {
+ }
+ Option(T&& data)
+ : m_none(false)
+ , m_data(data)
+ {
+ }
+ Option(const T& data)
+ : m_none(false)
+ , m_data(data)
+ {
+ }
+ template<class... Args>
+ Option(Args&&... args)
+ : m_none(false)
+ , m_data(args...)
+ {
+ }
+
+ T&& unwrap()
+ {
+ if (m_none) {
+ throw std::runtime_error("none option value");
+ }
+ m_none = true;
+ return std::move(m_data);
+ }
+ bool empty() const
+ { return m_none; }
+private:
+ bool m_none;
+ T m_data;
+};
+
+
+}
diff --git a/src/fwk/base/propertybag.cpp b/src/fwk/base/propertybag.cpp
index 61eccf4..64b6072 100644
--- a/src/fwk/base/propertybag.cpp
+++ b/src/fwk/base/propertybag.cpp
@@ -1,7 +1,7 @@
/*
* niepce - fwk/base/propertybag.cpp
*
- * Copyright (C) 2011-2013 Hubert Figuiere
+ * Copyright (C) 2011-2017 Hubert Figuiere
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,15 +55,14 @@ bool PropertyBag::set_value_for_property(PropertyIndex idx, const PropertyValue
return removed;
}
-/** return true if a property is found */
-bool PropertyBag::get_value_for_property(PropertyIndex idx, PropertyValue & value) const
+/** return an option */
+fwk::Option<PropertyValue> PropertyBag::get_value_for_property(PropertyIndex idx) const
{
_Map::const_iterator iter = m_bag.find(idx);
if(iter == m_bag.end()) {
return false;
}
- value = iter->second;
- return true;
+ return fwk::Option<PropertyValue>(iter->second);
}
bool PropertyBag::has_value_for_property(PropertyIndex idx) const
diff --git a/src/fwk/base/propertybag.hpp b/src/fwk/base/propertybag.hpp
index 74d2aa5..111689a 100644
--- a/src/fwk/base/propertybag.hpp
+++ b/src/fwk/base/propertybag.hpp
@@ -29,6 +29,7 @@
#include <boost/variant.hpp>
#include "fwk/base/date.hpp"
+#include "fwk/base/option.hpp"
namespace fwk {
@@ -88,8 +89,8 @@ public:
/** return true if a property was removed prior to insertion */
bool set_value_for_property(PropertyIndex idx, const PropertyValue & value);
- /** return true if a property is found */
- bool get_value_for_property(PropertyIndex idx, PropertyValue & value) const;
+ /** return property or an empty option */
+ fwk::Option<PropertyValue> get_value_for_property(PropertyIndex idx) const;
/** return true if property exist */
bool has_value_for_property(PropertyIndex idx) const;
/** return true if the property was removed */
diff --git a/src/fwk/base/t/testoption.cpp b/src/fwk/base/t/testoption.cpp
new file mode 100644
index 0000000..015df02
--- /dev/null
+++ b/src/fwk/base/t/testoption.cpp
@@ -0,0 +1,67 @@
+/*
+ * niepce - fwk/base/t/testoption.cpp
+ *
+ * Copyright (C) 2017 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/** @brief unit test for option */
+
+#include <boost/test/minimal.hpp>
+
+#include <stdlib.h>
+
+#include <string>
+
+#include "fwk/base/option.hpp"
+
+int test_main( int, char *[] ) // note the name!
+{
+ fwk::Option<std::string> result;
+
+ // Default, option is empty
+ BOOST_CHECK(result.empty());
+ bool unwrapped = false;
+ try {
+ result.unwrap();
+ unwrapped = true;
+ } catch(std::runtime_error&) {
+ BOOST_CHECK(true);
+ } catch(...) {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK(!unwrapped);
+ BOOST_CHECK(result.empty());
+
+ // Option with value
+ result = fwk::Option<std::string>("hello world");
+ BOOST_CHECK(!result.empty());
+ BOOST_CHECK(result.unwrap() == "hello world");
+ BOOST_CHECK(result.empty());
+ // try unwrapping again
+ unwrapped = false;
+ try {
+ result.unwrap();
+ unwrapped = true;
+ } catch(std::runtime_error&) {
+ BOOST_CHECK(true);
+ } catch(...) {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK(!unwrapped);
+ BOOST_CHECK(result.empty());
+
+ return 0;
+}
+
diff --git a/src/fwk/toolkit/metadatawidget.cpp b/src/fwk/toolkit/metadatawidget.cpp
index c3f98fd..6852312 100644
--- a/src/fwk/toolkit/metadatawidget.cpp
+++ b/src/fwk/toolkit/metadatawidget.cpp
@@ -1,7 +1,7 @@
/*
* niepce - fwk/toolkit/metadatawidget.cpp
*
- * Copyright (C) 2008-2013 Hubert Figuiere
+ * Copyright (C) 2008-2017 Hubert Figuiere
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -241,9 +241,9 @@ void MetaDataWidget::set_data_source(const fwk::PropertyBag & properties)
const MetaDataFormat * current = m_fmt->formats;
while(current && current->label) {
- PropertyValue v;
- if(properties.get_value_for_property(current->id, v) || !current->readonly) {
- add_data(current, v);
+ auto result = properties.get_value_for_property(current->id);
+ if(!result.empty() || !current->readonly) {
+ add_data(current, result.unwrap());
}
else {
DBG_OUT("get_property failed id = %d, label = %s",
@@ -474,14 +474,14 @@ void MetaDataWidget::on_int_changed(int value, fwk::PropertyIndex prop)
emit_metadata_changed(prop, fwk::PropertyValue(value));
}
-void MetaDataWidget::emit_metadata_changed(fwk::PropertyIndex prop,
+void MetaDataWidget::emit_metadata_changed(fwk::PropertyIndex prop,
const fwk::PropertyValue & value)
{
fwk::PropertyBag props, old_props;
props.set_value_for_property(prop, value);
- fwk::PropertyValue old_value;
- if(m_current_data.get_value_for_property(prop, old_value)) {
- old_props.set_value_for_property(prop, old_value);
+ auto result = m_current_data.get_value_for_property(prop);
+ if (!result.empty()) {
+ old_props.set_value_for_property(prop, result.unwrap());
}
signal_metadata_changed.emit(props, old_props);
}
diff --git a/src/niepce/modules/map/mapmodule.cpp b/src/niepce/modules/map/mapmodule.cpp
index 9ed8271..bfddc54 100644
--- a/src/niepce/modules/map/mapmodule.cpp
+++ b/src/niepce/modules/map/mapmodule.cpp
@@ -1,7 +1,7 @@
/*
* niepce - modules/map/mapmodule.cpp
*
- * Copyright (C) 2014 Hubert Figuiere
+ * Copyright (C) 2014-2017 Hubert Figuiere
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -84,15 +84,18 @@ MapModule::on_lib_notification(const eng::LibNotification &ln)
lm->to_properties(propset, properties);
double latitude, longitude;
latitude = longitude = NAN;
- fwk::PropertyValue val;
- if(properties.get_value_for_property(eng::NpExifGpsLongProp, val)) {
+ auto result = properties.get_value_for_property(eng::NpExifGpsLongProp);
+ if (!result.empty()) {
+ fwk::PropertyValue val = result.unwrap();
// it is a string
if (is_string(val)) {
longitude = fwk::XmpMeta::gpsCoordFromXmp(
fwk::get_string(val));
}
}
- if(properties.get_value_for_property(eng::NpExifGpsLatProp, val)) {
+ result = properties.get_value_for_property(eng::NpExifGpsLatProp);
+ if (!result.empty()) {
+ fwk::PropertyValue val = result.unwrap();
// it is a string
if (is_string(val)) {
latitude = fwk::XmpMeta::gpsCoordFromXmp(
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index cf7d2ba..65ba552 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -1,7 +1,7 @@
/*
* niepce - niepce/ui/selectioncontroller.cpp
*
- * Copyright (C) 2008-2014 Hubert Figuiere
+ * Copyright (C) 2008-2017 Hubert Figuiere
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -217,11 +217,14 @@ bool SelectionController::_set_metadata(const std::string & undo_label,
auto undo = fwk::Application::app()->begin_undo(undo_label);
for(auto iter : props) {
fwk::PropertyValue value;
- old.get_value_for_property(iter.first, value);
+ auto result = old.get_value_for_property(iter.first);
- if(value.type() != typeid(fwk::EmptyValue)) {
- DBG_ASSERT(value.type() == iter.second.type(),
- "Value type mismatch");
+ if (!result.empty()) {
+ value = result.unwrap();
+ if(value.type() != typeid(fwk::EmptyValue)) {
+ DBG_ASSERT(value.type() == iter.second.type(),
+ "Value type mismatch");
+ }
}
undo->new_command<void>(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]