]> git.tdb.fi Git - builder.git/blobdiff - source/lib/sourcepackage.h
Correct MSVC tools' input suffixes
[builder.git] / source / lib / sourcepackage.h
index 8be8ada63d654f68a963feb55cdec9f8c7544d77..2c2e57c70a4503e8f21ad980cda88ac1e84f935e 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef SOURCEPACKAGE_H_
 #define SOURCEPACKAGE_H_
 
+#include <algorithm>
 #include <stdexcept>
 #include <string>
+#include <msp/core/typeregistry.h>
 #include "buildinfo.h"
 #include "cache.h"
 #include "component.h"
@@ -25,7 +27,15 @@ class SourcePackage: public Package
 public:
        class Loader: public Msp::DataFile::DerivedObjectLoader<SourcePackage, Package::Loader>, public FeatureConditional
        {
+               friend class SourcePackage;
+
        private:
+               template<typename T>
+               struct AddComponent
+               {
+                       void operator()(const std::string &n, Loader &l) const { l.add(n, &Loader::component<T>); }
+               };
+
                const Config::InputOptions *options;
 
        public:
@@ -34,10 +44,8 @@ public:
                void finish() override;
 
                void feature(const std::string &, const std::string &);
-               template<typename C>
-               void component(const std::string &);
-               template<typename C, typename A>
-               void component_arg(A, const std::string &);
+               template<typename C, typename... Args>
+               void component(Args..., const std::string &);
                void build_info();
                void generate(const std::string &);
                void interface_version(const std::string &);
@@ -46,6 +54,8 @@ public:
                void version(const std::string &);
        };
 
+       using ComponentRegistry = Msp::TypeRegistry<Loader::AddComponent, Loader &>;
+
 private:
        std::string version;
        std::string interface_version;
@@ -90,4 +100,15 @@ private:
        void save_caches() override;
 };
 
+
+template<typename C, typename... Args>
+void SourcePackage::Loader::component(Args... args, const std::string &n)
+{
+       if(std::any_of(obj.components.begin(), obj.components.end(), [&n](const Component *c){ return c->get_name()==n; }))
+               throw Msp::key_error(n);
+       C *comp = new C(obj, n, args...);
+       load_sub(*comp);
+       obj.components.push_back(comp);
+}
+
 #endif