fw: UnsolicitedDataPolicy registry

refs #2181

Change-Id: I39f5dd02a224f9d872bde29f29aab05f64bb6e06
diff --git a/daemon/fw/unsolicited-data-policy.hpp b/daemon/fw/unsolicited-data-policy.hpp
index f6ca771..62b64dc 100644
--- a/daemon/fw/unsolicited-data-policy.hpp
+++ b/daemon/fw/unsolicited-data-policy.hpp
@@ -54,6 +54,28 @@
 
   virtual UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const = 0;
+
+public: // registry
+  template<typename P>
+  static void
+  registerPolicy(const std::string& key)
+  {
+    Registry& registry = getRegistry();
+    BOOST_ASSERT(registry.count(key) == 0);
+    registry[key] = [] { return make_unique<P>(); };
+  }
+
+  /** \return an UnsolicitedDataPolicy identified by \p key, or nullptr if \p key is unknown
+   */
+  static unique_ptr<UnsolicitedDataPolicy>
+  create(const std::string& key);
+
+private:
+  typedef std::function<unique_ptr<UnsolicitedDataPolicy>()> CreateFunc;
+  typedef std::map<std::string, CreateFunc> Registry; // indexed by key
+
+  static Registry&
+  getRegistry();
 };
 
 /** \brief drops all unsolicited Data
@@ -92,11 +114,6 @@
   decide(const Face& inFace, const Data& data) const final;
 };
 
-/** \return an UnsolicitedDataPolicy identified by \p key, or nullptr if \p key is unknown
- */
-unique_ptr<UnsolicitedDataPolicy>
-makeUnsolicitedDataPolicy(const std::string& key);
-
 /** \brief the default UnsolicitedDataPolicy
  */
 typedef DropAllUnsolicitedDataPolicy DefaultUnsolicitedDataPolicy;
@@ -104,4 +121,18 @@
 } // namespace fw
 } // namespace nfd
 
+/** \brief registers an unsolicited data policy
+ *  \param P a subclass of nfd::fw::UnsolicitedDataPolicy
+ *  \param key the policy keyword, which is available for selection in NFD config file
+ */
+#define NFD_REGISTER_UNSOLICITED_DATA_POLICY(P, key)                \
+static class NfdAuto ## P ## UnsolicitedDataPolicyRegistrationClass \
+{                                                                   \
+public:                                                             \
+  NfdAuto ## P ## UnsolicitedDataPolicyRegistrationClass()          \
+  {                                                                 \
+    ::nfd::fw::UnsolicitedDataPolicy::registerPolicy<P>(key);       \
+  }                                                                 \
+} g_nfdAuto ## P ## UnsolicitedDataPolicyRegistrationVariable
+
 #endif // NFD_DAEMON_FW_UNSOLICITED_DATA_POLICY_HPP