mgmt: use std::bitset in ControlParameters

Change-Id: I86511f29e230c828882fa958becb868fd38f4786
diff --git a/ndn-cxx/mgmt/nfd/control-command.cpp b/ndn-cxx/mgmt/nfd/control-command.cpp
index 6e90f84..c6f67e2 100644
--- a/ndn-cxx/mgmt/nfd/control-command.cpp
+++ b/ndn-cxx/mgmt/nfd/control-command.cpp
@@ -26,9 +26,11 @@
 void
 ControlParametersCommandFormat::validate(const ControlParameters& parameters) const
 {
-  const auto& presentFields = parameters.getPresentFields();
+  auto presentFields = parameters.getPresentFields();
+  BOOST_ASSERT(presentFields.size() == m_required.size() &&
+               presentFields.size() == m_optional.size());
 
-  for (size_t i = 0; i < CONTROL_PARAMETER_UBOUND; ++i) {
+  for (size_t i = 0; i < presentFields.size(); ++i) {
     bool isPresent = presentFields[i];
     if (m_required[i]) {
       if (!isPresent) {
diff --git a/ndn-cxx/mgmt/nfd/control-parameters.cpp b/ndn-cxx/mgmt/nfd/control-parameters.cpp
index 1783ce8..26af540 100644
--- a/ndn-cxx/mgmt/nfd/control-parameters.cpp
+++ b/ndn-cxx/mgmt/nfd/control-parameters.cpp
@@ -26,13 +26,11 @@
 
 namespace ndn::nfd {
 
-ControlParameters::ControlParameters()
-  : m_hasFields(CONTROL_PARAMETER_UBOUND)
-{
-}
+static_assert(CONTROL_PARAMETER_FIELD.size() == CONTROL_PARAMETER_UBOUND);
+
+ControlParameters::ControlParameters() = default;
 
 ControlParameters::ControlParameters(const Block& block)
-  : m_hasFields(CONTROL_PARAMETER_UBOUND)
 {
   wireDecode(block);
 }
@@ -132,47 +130,47 @@
   for (const auto& e : m_wire.elements()) {
     switch (e.type()) {
     case tlv::Name:
-      m_hasFields[CONTROL_PARAMETER_NAME] = true;
+      m_hasFields.set(CONTROL_PARAMETER_NAME);
       m_name.wireDecode(e);
       break;
     case tlv::nfd::FaceId:
-      m_hasFields[CONTROL_PARAMETER_FACE_ID] = true;
+      m_hasFields.set(CONTROL_PARAMETER_FACE_ID);
       m_faceId = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Uri:
-      m_hasFields[CONTROL_PARAMETER_URI] = true;
+      m_hasFields.set(CONTROL_PARAMETER_URI);
       m_uri = readString(e);
       break;
     case tlv::nfd::LocalUri:
-      m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = true;
+      m_hasFields.set(CONTROL_PARAMETER_LOCAL_URI);
       m_localUri = readString(e);
       break;
     case tlv::nfd::Origin:
-      m_hasFields[CONTROL_PARAMETER_ORIGIN] = true;
+      m_hasFields.set(CONTROL_PARAMETER_ORIGIN);
       m_origin = readNonNegativeIntegerAs<RouteOrigin>(e);
       break;
     case tlv::nfd::Cost:
-      m_hasFields[CONTROL_PARAMETER_COST] = true;
+      m_hasFields.set(CONTROL_PARAMETER_COST);
       m_cost = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Capacity:
-      m_hasFields[CONTROL_PARAMETER_CAPACITY] = true;
+      m_hasFields.set(CONTROL_PARAMETER_CAPACITY);
       m_capacity = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Count:
-      m_hasFields[CONTROL_PARAMETER_COUNT] = true;
+      m_hasFields.set(CONTROL_PARAMETER_COUNT);
       m_count = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Flags:
-      m_hasFields[CONTROL_PARAMETER_FLAGS] = true;
+      m_hasFields.set(CONTROL_PARAMETER_FLAGS);
       m_flags = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Mask:
-      m_hasFields[CONTROL_PARAMETER_MASK] = true;
+      m_hasFields.set(CONTROL_PARAMETER_MASK);
       m_mask = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Strategy:
-      m_hasFields[CONTROL_PARAMETER_STRATEGY] = true;
+      m_hasFields.set(CONTROL_PARAMETER_STRATEGY);
       e.parse();
       if (e.elements().empty()) {
         NDN_THROW(Error("Expecting Strategy.Name"));
@@ -180,23 +178,23 @@
       m_strategy.wireDecode(e.elements().front());
       break;
     case tlv::nfd::ExpirationPeriod:
-      m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = true;
+      m_hasFields.set(CONTROL_PARAMETER_EXPIRATION_PERIOD);
       m_expirationPeriod = time::milliseconds(readNonNegativeInteger(e));
       break;
     case tlv::nfd::FacePersistency:
-      m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = true;
+      m_hasFields.set(CONTROL_PARAMETER_FACE_PERSISTENCY);
       m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(e);
       break;
     case tlv::nfd::BaseCongestionMarkingInterval:
-      m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = true;
+      m_hasFields.set(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL);
       m_baseCongestionMarkingInterval = time::nanoseconds(readNonNegativeInteger(e));
       break;
     case tlv::nfd::DefaultCongestionThreshold:
-      m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = true;
+      m_hasFields.set(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD);
       m_defaultCongestionThreshold = readNonNegativeInteger(e);
       break;
     case tlv::nfd::Mtu:
-      m_hasFields[CONTROL_PARAMETER_MTU] = true;
+      m_hasFields.set(CONTROL_PARAMETER_MTU);
       m_mtu = readNonNegativeInteger(e);
       break;
     default:
@@ -235,7 +233,7 @@
 }
 
 ControlParameters&
-ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
+ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask)
 {
   if (bit >= 64) {
     NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
diff --git a/ndn-cxx/mgmt/nfd/control-parameters.hpp b/ndn-cxx/mgmt/nfd/control-parameters.hpp
index 8120abd..3389bd3 100644
--- a/ndn-cxx/mgmt/nfd/control-parameters.hpp
+++ b/ndn-cxx/mgmt/nfd/control-parameters.hpp
@@ -27,6 +27,9 @@
 #include "ndn-cxx/mgmt/control-parameters-base.hpp"
 #include "ndn-cxx/util/time.hpp"
 
+#include <array>
+#include <bitset>
+
 namespace ndn::nfd {
 
 /**
@@ -52,7 +55,7 @@
   CONTROL_PARAMETER_UBOUND,
 };
 
-inline constexpr std::string_view CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
+inline constexpr std::array CONTROL_PARAMETER_FIELD = {
   "Name"sv,
   "FaceId"sv,
   "Uri"sv,
@@ -120,7 +123,7 @@
   {
     m_wire.reset();
     m_name = name;
-    m_hasFields[CONTROL_PARAMETER_NAME] = true;
+    m_hasFields.set(CONTROL_PARAMETER_NAME);
     return *this;
   }
 
@@ -128,7 +131,7 @@
   unsetName()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_NAME] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_NAME);
     return *this;
   }
 
@@ -150,7 +153,7 @@
   {
     m_wire.reset();
     m_faceId = faceId;
-    m_hasFields[CONTROL_PARAMETER_FACE_ID] = true;
+    m_hasFields.set(CONTROL_PARAMETER_FACE_ID);
     return *this;
   }
 
@@ -158,7 +161,7 @@
   unsetFaceId()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_FACE_ID] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_FACE_ID);
     return *this;
   }
 
@@ -180,7 +183,7 @@
   {
     m_wire.reset();
     m_uri = uri;
-    m_hasFields[CONTROL_PARAMETER_URI] = true;
+    m_hasFields.set(CONTROL_PARAMETER_URI);
     return *this;
   }
 
@@ -188,7 +191,7 @@
   unsetUri()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_URI] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_URI);
     return *this;
   }
 
@@ -210,7 +213,7 @@
   {
     m_wire.reset();
     m_localUri = localUri;
-    m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = true;
+    m_hasFields.set(CONTROL_PARAMETER_LOCAL_URI);
     return *this;
   }
 
@@ -218,7 +221,7 @@
   unsetLocalUri()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_LOCAL_URI);
     return *this;
   }
 
@@ -240,7 +243,7 @@
   {
     m_wire.reset();
     m_origin = origin;
-    m_hasFields[CONTROL_PARAMETER_ORIGIN] = true;
+    m_hasFields.set(CONTROL_PARAMETER_ORIGIN);
     return *this;
   }
 
@@ -248,7 +251,7 @@
   unsetOrigin()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_ORIGIN] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_ORIGIN);
     return *this;
   }
 
@@ -270,7 +273,7 @@
   {
     m_wire.reset();
     m_cost = cost;
-    m_hasFields[CONTROL_PARAMETER_COST] = true;
+    m_hasFields.set(CONTROL_PARAMETER_COST);
     return *this;
   }
 
@@ -278,7 +281,7 @@
   unsetCost()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_COST] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_COST);
     return *this;
   }
 
@@ -300,7 +303,7 @@
   {
     m_wire.reset();
     m_capacity = capacity;
-    m_hasFields[CONTROL_PARAMETER_CAPACITY] = true;
+    m_hasFields.set(CONTROL_PARAMETER_CAPACITY);
     return *this;
   }
 
@@ -308,7 +311,7 @@
   unsetCapacity()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_CAPACITY] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_CAPACITY);
     return *this;
   }
 
@@ -330,7 +333,7 @@
   {
     m_wire.reset();
     m_count = count;
-    m_hasFields[CONTROL_PARAMETER_COUNT] = true;
+    m_hasFields.set(CONTROL_PARAMETER_COUNT);
     return *this;
   }
 
@@ -338,7 +341,7 @@
   unsetCount()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_COUNT] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_COUNT);
     return *this;
   }
 
@@ -360,7 +363,7 @@
   {
     m_wire.reset();
     m_flags = flags;
-    m_hasFields[CONTROL_PARAMETER_FLAGS] = true;
+    m_hasFields.set(CONTROL_PARAMETER_FLAGS);
     return *this;
   }
 
@@ -368,7 +371,7 @@
   unsetFlags()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_FLAGS] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_FLAGS);
     return *this;
   }
 
@@ -390,7 +393,7 @@
   {
     m_wire.reset();
     m_mask = mask;
-    m_hasFields[CONTROL_PARAMETER_MASK] = true;
+    m_hasFields.set(CONTROL_PARAMETER_MASK);
     return *this;
   }
 
@@ -398,7 +401,7 @@
   unsetMask()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_MASK] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_MASK);
     return *this;
   }
 
@@ -420,7 +423,7 @@
   {
     m_wire.reset();
     m_strategy = strategy;
-    m_hasFields[CONTROL_PARAMETER_STRATEGY] = true;
+    m_hasFields.set(CONTROL_PARAMETER_STRATEGY);
     return *this;
   }
 
@@ -428,7 +431,7 @@
   unsetStrategy()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_STRATEGY] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_STRATEGY);
     return *this;
   }
 
@@ -450,7 +453,7 @@
   {
     m_wire.reset();
     m_expirationPeriod = expirationPeriod;
-    m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = true;
+    m_hasFields.set(CONTROL_PARAMETER_EXPIRATION_PERIOD);
     return *this;
   }
 
@@ -458,7 +461,7 @@
   unsetExpirationPeriod()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_EXPIRATION_PERIOD);
     return *this;
   }
 
@@ -480,7 +483,7 @@
   {
     m_wire.reset();
     m_facePersistency = persistency;
-    m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = true;
+    m_hasFields.set(CONTROL_PARAMETER_FACE_PERSISTENCY);
     return *this;
   }
 
@@ -488,7 +491,7 @@
   unsetFacePersistency()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_FACE_PERSISTENCY);
     return *this;
   }
 
@@ -510,7 +513,7 @@
   {
     m_wire.reset();
     m_baseCongestionMarkingInterval = interval;
-    m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = true;
+    m_hasFields.set(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL);
     return *this;
   }
 
@@ -518,7 +521,7 @@
   unsetBaseCongestionMarkingInterval()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL);
     return *this;
   }
 
@@ -544,7 +547,7 @@
   {
     m_wire.reset();
     m_defaultCongestionThreshold = threshold;
-    m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = true;
+    m_hasFields.set(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD);
     return *this;
   }
 
@@ -552,7 +555,7 @@
   unsetDefaultCongestionThreshold()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD);
     return *this;
   }
 
@@ -582,7 +585,7 @@
   {
     m_wire.reset();
     m_mtu = mtu;
-    m_hasFields[CONTROL_PARAMETER_MTU] = true;
+    m_hasFields.set(CONTROL_PARAMETER_MTU);
     return *this;
   }
 
@@ -590,12 +593,12 @@
   unsetMtu()
   {
     m_wire.reset();
-    m_hasFields[CONTROL_PARAMETER_MTU] = false;
+    m_hasFields.reset(CONTROL_PARAMETER_MTU);
     return *this;
   }
 
-  const std::vector<bool>&
-  getPresentFields() const
+  auto
+  getPresentFields() const noexcept
   {
     return m_hasFields;
   }
@@ -632,8 +635,8 @@
   ControlParameters&
   unsetFlagBit(size_t bit);
 
-private: // fields
-  std::vector<bool>   m_hasFields;
+private:
+  std::bitset<CONTROL_PARAMETER_UBOUND> m_hasFields;
 
   Name                m_name;
   uint64_t            m_faceId;
@@ -652,7 +655,6 @@
   uint64_t            m_defaultCongestionThreshold;
   uint64_t            m_mtu;
 
-private:
   mutable Block m_wire;
 };