From a1e5d6fbd3fcb96c5c29f62f8696dc8a8fcf3a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Wed, 11 Dec 2024 18:14:55 +0100 Subject: [PATCH] core: Use enum class for TypeId::SupportLevel --- CHANGES.md | 1 + .../model/three-gpp-http-client.cc | 4 +-- .../model/three-gpp-http-server.cc | 4 +-- src/applications/model/udp-client.cc | 4 +-- src/applications/model/udp-echo-client.cc | 4 +-- src/applications/model/udp-trace-client.cc | 4 +-- src/config-store/model/attribute-iterator.cc | 4 +-- src/config-store/model/config-store.cc | 2 +- src/core/model/type-id.cc | 33 ++++++++++++++----- src/core/model/type-id.h | 32 +++++++++++++++--- src/core/test/attribute-test-suite.cc | 2 +- src/core/test/type-id-test-suite.cc | 20 ++++++----- src/internet/model/ipv4.cc | 2 +- src/tap-bridge/model/tap-bridge.cc | 2 +- src/wifi/model/txop.cc | 8 ++--- src/wifi/model/wifi-net-device.cc | 2 +- src/wifi/model/wifi-remote-station-manager.cc | 4 +-- utils/print-introspected-doxygen.cc | 18 ++-------- 18 files changed, 90 insertions(+), 60 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 926120b91..d369cb34a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,7 @@ This file is a best-effort approach to solving this issue; we will do our best b * (applications) Deprecated attributes `RemoteAddress` and `RemotePort` in UdpClient, UdpTraceClient and UdpEchoClient. They have been combined into a single `Remote` attribute. * (applications) Deprecated attributes `ThreeGppHttpClient::RemoteServerAddress` and `ThreeGppHttpClient::RemoteServerPort`. They have been combined into a single `ThreeGppHttpClient::Remote` attribute. +* (core) Deprecated `SUPPORTED`, `DEPRECATED` and `OBSOLETE` in `TypeId` class. They have been replaced by `SupportLevel::{SUPPORTED,DEPRECATED,OBSOLETE}`, respectively. * (lr-wpan) ``LrWpanMac`` is now also aggregated to ``LrWpanNetDevice``. * (stats) Deprecated ns3::NaN and ns3::isNaN to use std::nan and std::isnan in their place * (tap-bridge) Deprecated "Gateway" attribute. diff --git a/src/applications/model/three-gpp-http-client.cc b/src/applications/model/three-gpp-http-client.cc index 5cd1ac2cf..f879301d3 100644 --- a/src/applications/model/three-gpp-http-client.cc +++ b/src/applications/model/three-gpp-http-client.cc @@ -64,14 +64,14 @@ ThreeGppHttpClient::GetTypeId() AddressValue(), MakeAddressAccessor(&ThreeGppHttpClient::SetRemote), MakeAddressChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute("RemoteServerPort", "The destination port of the outbound packets.", UintegerValue(80), // the default HTTP port MakeUintegerAccessor(&ThreeGppHttpClient::SetPort), MakeUintegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddTraceSource("RxPage", "A page has been received.", diff --git a/src/applications/model/three-gpp-http-server.cc b/src/applications/model/three-gpp-http-server.cc index c05e76dc8..cde5623bf 100644 --- a/src/applications/model/three-gpp-http-server.cc +++ b/src/applications/model/three-gpp-http-server.cc @@ -65,14 +65,14 @@ ThreeGppHttpServer::GetTypeId() AddressValue(), MakeAddressAccessor(&ThreeGppHttpServer::SetLocal), MakeAddressChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Local in ns-3.44.") .AddAttribute("LocalPort", "Port on which the application listen for incoming packets.", UintegerValue(80), // the default HTTP port MakeUintegerAccessor(&ThreeGppHttpServer::SetPort), MakeUintegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Port in ns-3.44.") .AddAttribute("Tos", "The Type of Service used to send packets. " diff --git a/src/applications/model/udp-client.cc b/src/applications/model/udp-client.cc index 3cc9484b3..f190d66bc 100644 --- a/src/applications/model/udp-client.cc +++ b/src/applications/model/udp-client.cc @@ -58,14 +58,14 @@ UdpClient::GetTypeId() // of the function overload to use &UdpClient::GetRemote), MakeAddressChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute("RemotePort", "The destination port of the outbound packets", UintegerValue(UdpClient::DEFAULT_PORT), MakeUintegerAccessor(&UdpClient::SetPort, &UdpClient::GetPort), MakeUintegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute("PacketSize", "Size of packets generated. The minimum packet size is 12 bytes which is " diff --git a/src/applications/model/udp-echo-client.cc b/src/applications/model/udp-echo-client.cc index 611731923..4cec49c1a 100644 --- a/src/applications/model/udp-echo-client.cc +++ b/src/applications/model/udp-echo-client.cc @@ -51,14 +51,14 @@ UdpEchoClient::GetTypeId() // function overload to use &UdpEchoClient::GetRemote), MakeAddressChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute("RemotePort", "The destination port of the outbound packets", UintegerValue(UdpEchoClient::DEFAULT_PORT), MakeUintegerAccessor(&UdpEchoClient::SetPort, &UdpEchoClient::GetPort), MakeUintegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute( "PacketSize", diff --git a/src/applications/model/udp-trace-client.cc b/src/applications/model/udp-trace-client.cc index 155809e9a..24dabbe09 100644 --- a/src/applications/model/udp-trace-client.cc +++ b/src/applications/model/udp-trace-client.cc @@ -64,7 +64,7 @@ UdpTraceClient::GetTypeId() UdpTraceClient::SetRemote), // this is needed to indicate which // version of the function overload to use MakeAddressChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute( "RemotePort", @@ -76,7 +76,7 @@ UdpTraceClient::GetTypeId() // the function overload to use &UdpTraceClient::GetRemote), MakeUintegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "Replaced by Remote in ns-3.44.") .AddAttribute("MaxPacketSize", "The maximum size of a packet (including the SeqTsHeader, 12 bytes).", diff --git a/src/config-store/model/attribute-iterator.cc b/src/config-store/model/attribute-iterator.cc index 80d7d899c..10917c243 100644 --- a/src/config-store/model/attribute-iterator.cc +++ b/src/config-store/model/attribute-iterator.cc @@ -220,8 +220,8 @@ AttributeIterator::DoIterate(Ptr object) if (ptrChecker != nullptr) { NS_LOG_DEBUG("pointer attribute " << info.name); - if (info.supportLevel == TypeId::DEPRECATED || - info.supportLevel == TypeId::OBSOLETE) + if (info.supportLevel == TypeId::SupportLevel::DEPRECATED || + info.supportLevel == TypeId::SupportLevel::OBSOLETE) { continue; } diff --git a/src/config-store/model/config-store.cc b/src/config-store/model/config-store.cc index 5ba7769df..ec3531e09 100644 --- a/src/config-store/model/config-store.cc +++ b/src/config-store/model/config-store.cc @@ -68,7 +68,7 @@ ConfigStore::GetTypeId() BooleanValue(true), MakeBooleanAccessor(&ConfigStore::SetSaveDeprecated), MakeBooleanChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "OBSOLETE since ns-3.43 as it is no longer needed; deprecated attributes are saved " "only if their value differs from their respective original initial value"); return tid; diff --git a/src/core/model/type-id.cc b/src/core/model/type-id.cc index 21014b562..531ded91f 100644 --- a/src/core/model/type-id.cc +++ b/src/core/model/type-id.cc @@ -207,7 +207,7 @@ class IidManager : public Singleton Ptr initialValue, Ptr accessor, Ptr checker, - TypeId::SupportLevel supportLevel = TypeId::SUPPORTED, + TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED, const std::string& supportMsg = ""); /** * Set the initial value of an Attribute. @@ -250,7 +250,7 @@ class IidManager : public Singleton std::string help, Ptr accessor, std::string callback, - TypeId::SupportLevel supportLevel = TypeId::SUPPORTED, + TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED, const std::string& supportMsg = ""); /** * Get the number of Trace sources. @@ -444,7 +444,7 @@ IidManager::AllocateUid(std::string name) information.size = (std::size_t)(-1); information.hasConstructor = false; information.mustHideFromDocumentation = false; - information.supportLevel = TypeId::SUPPORTED; + information.supportLevel = TypeId::SupportLevel::SUPPORTED; m_information.push_back(information); std::size_t tuid = m_information.size(); NS_ASSERT(tuid <= 0xffff); @@ -973,12 +973,12 @@ TypeId::LookupAttributeByName(std::string name, auto [found, tid, attribute] = FindAttribute(*this, name); if (found) { - if (attribute.supportLevel == TypeId::SUPPORTED) + if (attribute.supportLevel == SupportLevel::SUPPORTED) { *info = attribute; return true; } - else if (attribute.supportLevel == TypeId::DEPRECATED) + else if (attribute.supportLevel == SupportLevel::DEPRECATED) { if (!permissive) { @@ -988,7 +988,7 @@ TypeId::LookupAttributeByName(std::string name, *info = attribute; return true; } - else if (attribute.supportLevel == TypeId::OBSOLETE) + else if (attribute.supportLevel == SupportLevel::OBSOLETE) { NS_FATAL_ERROR("Attribute '" << name << "' is obsolete, with no fallback: " << attribute.supportMsg); @@ -1240,19 +1240,19 @@ TypeId::LookupTraceSourceByName(std::string name, TraceSourceInformation* info) tmp = tid.GetTraceSource(i); if (tmp.name == name) { - if (tmp.supportLevel == TypeId::SUPPORTED) + if (tmp.supportLevel == SupportLevel::SUPPORTED) { *info = tmp; return tmp.accessor; } - else if (tmp.supportLevel == TypeId::DEPRECATED) + else if (tmp.supportLevel == SupportLevel::DEPRECATED) { std::cerr << "TraceSource '" << name << "' is deprecated: " << tmp.supportMsg << std::endl; *info = tmp; return tmp.accessor; } - else if (tmp.supportLevel == TypeId::OBSOLETE) + else if (tmp.supportLevel == SupportLevel::OBSOLETE) { NS_FATAL_ERROR("TraceSource '" << name << "' is obsolete, with no fallback: " << tmp.supportMsg); @@ -1317,6 +1317,21 @@ operator>>(std::istream& is, TypeId& tid) return is; } +std::ostream& +operator<<(std::ostream& os, TypeId::SupportLevel level) +{ + switch (level) + { + case TypeId::SupportLevel::SUPPORTED: + return os << "SUPPORTED"; + case TypeId::SupportLevel::DEPRECATED: + return os << "DEPRECATED"; + case TypeId::SupportLevel::OBSOLETE: + return os << "OBSOLETE"; + }; + return os << "UNKNOWN(" << static_cast(level) << ")"; +} + ATTRIBUTE_HELPER_CPP(TypeId); bool diff --git a/src/core/model/type-id.h b/src/core/model/type-id.h index 4b4625d4c..30eb5c32f 100644 --- a/src/core/model/type-id.h +++ b/src/core/model/type-id.h @@ -12,6 +12,7 @@ #include "attribute-helper.h" #include "attribute.h" #include "callback.h" +#include "deprecated.h" #include "hash.h" #include "trace-source-accessor.h" @@ -58,13 +59,28 @@ class TypeId }; /** The level of support or deprecation for attributes or trace sources. */ - enum SupportLevel + enum class SupportLevel { SUPPORTED, /**< Attribute or trace source is currently used. */ DEPRECATED, /**< Attribute or trace source is deprecated; user is warned. */ OBSOLETE /**< Attribute or trace source is not used anymore; simulation fails. */ }; + /** + * Deprecated support level simple enums. + * + * Use the `TypeId::SupportLevel` enum class symbols instead. + * @{ + */ + NS_DEPRECATED_3_44("Use SupportLevel::SUPPORTED instead") + static constexpr auto SUPPORTED = SupportLevel::SUPPORTED; + NS_DEPRECATED_3_44("Use SupportLevel::DEPRECATED instead") + static constexpr auto DEPRECATED = SupportLevel::DEPRECATED; + NS_DEPRECATED_3_44("Use SupportLevel::OBSOLETE instead") + static constexpr auto OBSOLETE = SupportLevel::OBSOLETE; + + /**@}*/ + /** Attribute implementation. */ struct AttributeInformation { @@ -389,7 +405,7 @@ class TypeId const AttributeValue& initialValue, Ptr accessor, Ptr checker, - SupportLevel supportLevel = SUPPORTED, + SupportLevel supportLevel = SupportLevel::SUPPORTED, const std::string& supportMsg = ""); /** @@ -429,7 +445,7 @@ class TypeId const AttributeValue& initialValue, Ptr accessor, Ptr checker, - SupportLevel supportLevel = SUPPORTED, + SupportLevel supportLevel = SupportLevel::SUPPORTED, const std::string& supportMsg = ""); /** @@ -458,7 +474,7 @@ class TypeId std::string help, Ptr accessor, std::string callback, - SupportLevel supportLevel = SUPPORTED, + SupportLevel supportLevel = SupportLevel::SUPPORTED, const std::string& supportMsg = ""); /** @@ -602,6 +618,14 @@ std::ostream& operator<<(std::ostream& os, TypeId tid); */ std::istream& operator>>(std::istream& is, TypeId& tid); +/** + * @brief Stream insertion operator. + * @param [in] os The reference to the output stream. + * @param [in] level The TypeId::SupportLevel. + * @return The reference to the output stream. + */ +std::ostream& operator<<(std::ostream& os, TypeId::SupportLevel level); + /** * Comparison operator. * @param [in] a One value. diff --git a/src/core/test/attribute-test-suite.cc b/src/core/test/attribute-test-suite.cc index 363a65732..5deb10a4f 100644 --- a/src/core/test/attribute-test-suite.cc +++ b/src/core/test/attribute-test-suite.cc @@ -339,7 +339,7 @@ class AttributeObjectTest : public Object BooleanValue(false), MakeBooleanAccessor(&AttributeObjectTest::m_boolTestDeprecated), MakeBooleanChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "DEPRECATED test working."); return tid; diff --git a/src/core/test/type-id-test-suite.cc b/src/core/test/type-id-test-suite.cc index e082af2f8..4dcb61c9c 100644 --- a/src/core/test/type-id-test-suite.cc +++ b/src/core/test/type-id-test-suite.cc @@ -237,7 +237,7 @@ class DeprecatedAttribute : public Object IntegerValue(1), MakeIntegerAccessor(&DeprecatedAttribute::m_attr), MakeIntegerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "use 'attribute' instead") // Obsolete attribute, as an example .AddAttribute("obsoleteAttribute", @@ -245,7 +245,7 @@ class DeprecatedAttribute : public Object EmptyAttributeValue(), MakeEmptyAttributeAccessor(), MakeEmptyAttributeChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "refactor to use 'attribute'") // The new trace source @@ -258,14 +258,14 @@ class DeprecatedAttribute : public Object "the old trace source", MakeTraceSourceAccessor(&DeprecatedAttribute::m_trace), "ns3::TracedValueCallback::Double", - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "use 'trace' instead") // Obsolete trace source, as an example .AddTraceSource("obsoleteTraceSource", "the obsolete trace source", MakeEmptyTraceSourceAccessor(), "ns3::TracedValueCallback::Void", - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "refactor to use 'trace'"); return tid; @@ -311,25 +311,29 @@ DeprecatedAttributeTestCase::DoRun() true, "lookup new attribute"); std::cerr << suite << "lookup new attribute:" - << (ainfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error") << std::endl; + << (ainfo.supportLevel == TypeId::SupportLevel::SUPPORTED ? "supported" : "error") + << std::endl; NS_TEST_ASSERT_MSG_EQ(tid.LookupAttributeByName("oldAttribute", &ainfo), true, "lookup old attribute"); std::cerr << suite << "lookup old attribute:" - << (ainfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error") << std::endl; + << (ainfo.supportLevel == TypeId::SupportLevel::DEPRECATED ? "deprecated" : "error") + << std::endl; TypeId::TraceSourceInformation tinfo; Ptr acc; acc = tid.LookupTraceSourceByName("trace", &tinfo); NS_TEST_ASSERT_MSG_NE(acc, nullptr, "lookup new trace source"); std::cerr << suite << "lookup new trace source:" - << (tinfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error") << std::endl; + << (tinfo.supportLevel == TypeId::SupportLevel::SUPPORTED ? "supported" : "error") + << std::endl; acc = tid.LookupTraceSourceByName("oldTrace", &tinfo); NS_TEST_ASSERT_MSG_NE(acc, nullptr, "lookup old trace source"); std::cerr << suite << "lookup old trace source:" - << (tinfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error") << std::endl; + << (tinfo.supportLevel == TypeId::SupportLevel::DEPRECATED ? "deprecated" : "error") + << std::endl; } /** diff --git a/src/internet/model/ipv4.cc b/src/internet/model/ipv4.cc index f0cbd0d16..937964831 100644 --- a/src/internet/model/ipv4.cc +++ b/src/internet/model/ipv4.cc @@ -41,7 +41,7 @@ Ipv4::GetTypeId() BooleanValue(true), MakeBooleanAccessor(&Ipv4::SetWeakEsModel, &Ipv4::GetWeakEsModel), MakeBooleanChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "DEPRECATED since ns-3.41. Use the StrongEndSystemModel attribute.") .AddAttribute( "StrongEndSystemModel", diff --git a/src/tap-bridge/model/tap-bridge.cc b/src/tap-bridge/model/tap-bridge.cc index a35fdb73f..9a75fdb7a 100644 --- a/src/tap-bridge/model/tap-bridge.cc +++ b/src/tap-bridge/model/tap-bridge.cc @@ -90,7 +90,7 @@ TapBridge::GetTypeId() Ipv4AddressValue("255.255.255.255"), MakeIpv4AddressAccessor(&TapBridge::m_tapGateway), MakeIpv4AddressChecker(), - TypeId::OBSOLETE) + TypeId::SupportLevel::OBSOLETE) .AddAttribute( "IpAddress", "The IP address to assign to the tap device, when in ConfigureLocal mode. " diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index abf999b71..e6360f034 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -73,7 +73,7 @@ Txop::GetTypeId() MakeUintegerAccessor((void(Txop::*)(uint32_t)) & Txop::SetMinCw, (uint32_t(Txop::*)() const) & Txop::GetMinCw), MakeUintegerChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use MinCws attribute instead of MinCw") .AddAttribute( "MinCws", @@ -93,7 +93,7 @@ Txop::GetTypeId() MakeUintegerAccessor((void(Txop::*)(uint32_t)) & Txop::SetMaxCw, (uint32_t(Txop::*)() const) & Txop::GetMaxCw), MakeUintegerChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use MaxCws attribute instead of MaxCw") .AddAttribute( "MaxCws", @@ -114,7 +114,7 @@ Txop::GetTypeId() MakeUintegerAccessor((void(Txop::*)(uint8_t)) & Txop::SetAifsn, (uint8_t(Txop::*)() const) & Txop::GetAifsn), MakeUintegerChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use Aifsns attribute instead of Aifsn") .AddAttribute( "Aifsns", @@ -134,7 +134,7 @@ Txop::GetTypeId() MakeTimeAccessor((void(Txop::*)(Time)) & Txop::SetTxopLimit, (Time(Txop::*)() const) & Txop::GetTxopLimit), MakeTimeChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use TxopLimits attribute instead of TxopLimit") .AddAttribute( "TxopLimits", diff --git a/src/wifi/model/wifi-net-device.cc b/src/wifi/model/wifi-net-device.cc index 1bfa61a75..c1b4372e2 100644 --- a/src/wifi/model/wifi-net-device.cc +++ b/src/wifi/model/wifi-net-device.cc @@ -49,7 +49,7 @@ WifiNetDevice::GetTypeId() PointerValue(), MakePointerAccessor(&WifiNetDevice::GetChannel), MakePointerChecker(), - TypeId::DEPRECATED, + TypeId::SupportLevel::DEPRECATED, "class WifiNetDevice; use the Channel " "attribute of WifiPhy") .AddAttribute("Phy", diff --git a/src/wifi/model/wifi-remote-station-manager.cc b/src/wifi/model/wifi-remote-station-manager.cc index 514929dcd..1ee231491 100644 --- a/src/wifi/model/wifi-remote-station-manager.cc +++ b/src/wifi/model/wifi-remote-station-manager.cc @@ -51,7 +51,7 @@ WifiRemoteStationManager::GetTypeId() UintegerValue(7), MakeUintegerAccessor(&WifiRemoteStationManager::SetMaxSsrc), MakeUintegerChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use WifiMac::FrameRetryLimit instead") .AddAttribute("MaxSlrc", "The maximum number of retransmission attempts for any packet with size " @@ -60,7 +60,7 @@ WifiRemoteStationManager::GetTypeId() UintegerValue(4), MakeUintegerAccessor(&WifiRemoteStationManager::SetMaxSlrc), MakeUintegerChecker(), - TypeId::OBSOLETE, + TypeId::SupportLevel::OBSOLETE, "Use WifiMac::FrameRetryLimit instead") .AddAttribute( "IncrementRetryCountUnderBa", diff --git a/utils/print-introspected-doxygen.cc b/utils/print-introspected-doxygen.cc index 6461c7676..7dffe9921 100644 --- a/utils/print-introspected-doxygen.cc +++ b/utils/print-introspected-doxygen.cc @@ -694,22 +694,8 @@ void PrintSupportLevel(std::ostream& os, TypeId::SupportLevel supportLevel, std::string supportMsg) { os << " " << listLineStart << "Support level: "; - os << flagSpanStart; - switch (supportLevel) - { - case TypeId::SUPPORTED: - os << "SUPPORTED"; - break; - case TypeId::DEPRECATED: - os << "DEPRECATED"; - break; - case TypeId::OBSOLETE: - os << "OBSOLETE"; - break; - default: - os << "UNKNOWN"; - } - os << flagSpanStop; + os << flagSpanStart << supportLevel << flagSpanStop; + if (!supportMsg.empty()) { os << ": " << supportMsg;