From 45260258d6f4cd90aecc9b71973575583c7ec0f3 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Fri, 13 Jun 2014 12:11:19 +0100 Subject: [PATCH] refs #245 & #210 moved TupleConverter's parsing of the stringified macro argument into a base class, ready for further extension --- src/blackmisc/tuple.cpp | 35 ++++++++++++++++++++++++++++++++ src/blackmisc/tuple.h | 45 ++++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/blackmisc/tuple.cpp diff --git a/src/blackmisc/tuple.cpp b/src/blackmisc/tuple.cpp new file mode 100644 index 000000000..bb627024a --- /dev/null +++ b/src/blackmisc/tuple.cpp @@ -0,0 +1,35 @@ +/* Copyright (C) 2014 VATSIM Community / authors + * 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 "tuple.h" + +namespace BlackMisc +{ + + TupleConverterBase::Parser::Parser(QString string) + { + string.remove(QRegExp("^\\s*\\(\\s*")); // remove first '(' + string.remove(QRegExp("\\s*\\)\\s*$")); // remove last ')' + QString current; + int level = 0; + for (const auto c : string) + { + if (c == '(') { level++; } + if (c == ')') { level++; } + if (c == ',' && level == 0) { m_raw.push_back(current.trimmed()); current.clear(); } + else { current += c; } + } + if (! current.trimmed().isEmpty()) { m_raw.push_back(current.trimmed()); current.clear(); } + + for (const auto &member : m_raw) + { + QRegExp simple("^o\\.(\\w+)$"); + if (member.contains(simple)) { m_names.push_back(simple.cap(1)); continue; } + qFatal("BLACK_DECLARE_TUPLE_CONVERSION: Parser couldn't extract member name from \"%s\"", qPrintable(member)); + } + for (auto &name : m_names) { name.remove(QRegExp("^m_")); } + } + +} // namespace diff --git a/src/blackmisc/tuple.h b/src/blackmisc/tuple.h index 7fe91f341..395bcb040 100644 --- a/src/blackmisc/tuple.h +++ b/src/blackmisc/tuple.h @@ -43,7 +43,7 @@ #define BLACK_DECLARE_TUPLE_CONVERSION(T, MEMBERS) \ namespace BlackMisc \ { \ - template <> class TupleConverter \ + template <> class TupleConverter : TupleConverterBase \ { \ friend class T; \ static_assert(Private::HasEnabledTupleConversion::value, \ @@ -56,10 +56,14 @@ { \ return BlackMisc::tie MEMBERS; \ } \ + static const Parser &parser() \ + { \ + static const Parser p(#MEMBERS); \ + return p; \ + } \ static const QStringList &jsonMembers() \ { \ - static QStringList members = QString(#MEMBERS).replace("tie(","").replace("(","").replace(")","").replace(" ","").replace("o.","").split(","); \ - return members; \ + return parser().m_names; \ } \ public: \ static auto constToTuple(const T &o) -> decltype(BlackMisc::tie MEMBERS) \ @@ -77,7 +81,7 @@ #define BLACK_DECLARE_TUPLE_CONVERSION_TEMPLATE(T, MEMBERS) \ namespace BlackMisc \ { \ - template class TupleConverter> \ + template class TupleConverter> : TupleConverterBase \ { \ friend class T; \ static_assert(Private::HasEnabledTupleConversion>::value, \ @@ -90,10 +94,14 @@ { \ return BlackMisc::tie MEMBERS; \ } \ + static const Parser &parser() \ + { \ + static const Parser p(#MEMBERS); \ + return p; \ + } \ static const QStringList &jsonMembers() \ { \ - static QStringList members = QString(#MEMBERS).replace("tie(","").replace("(","").replace(")","").replace(" ","").replace("o.","").split(","); \ - return members; \ + return parser().m_names; \ } \ public: \ static auto constToTuple(const T &o) -> decltype(BlackMisc::tie MEMBERS) \ @@ -106,6 +114,23 @@ namespace BlackMisc { + /*! + * \brief Base class for TupleConverter. + * \details Defines common types and functions which can be used inside the BLACK_DECLARE_TUPLE_CONVERSION() macro. + * \ingroup Tuples + */ + class TupleConverterBase + { + protected: + //! \brief Helper class which parses the stringified macro argument. + struct Parser + { + Parser(QString); //!< Constructor. + QStringList m_raw; //!< The raw macro argument, split by top-level commas. + QStringList m_names; //!< The names of the tuple members, stripped of any o.m_ prefix. + }; + }; + /*! * \brief Class template for converting class objects to tuples * \details If a class T uses the BLACK_ENABLE_TUPLE_CONVERSION() and BLACK_DECLARE_TUPLE_CONVERSION() macros, and object @@ -116,7 +141,7 @@ namespace BlackMisc * \nosubgrouping * \ingroup Tuples */ - template class TupleConverter + template class TupleConverter : private TupleConverterBase { // BLACK_DECLARE_TUPLE_CONVERSION generates an explicit specialization of TupleConverter, // so this unspecialized template will only be used if the macro is missing. It is also @@ -137,6 +162,12 @@ namespace BlackMisc static std::tuple<> constToTuple(const T &object); //! @} + /*! + * \name Static Private Member Functions + * \brief Returns an object with information extracted from the stringified macro argument. + */ + static const Parser &parser(); + /*! * \name Static Private Member Functions * \brief Returns a list of the names of the tuple members.