atlas
Factory.h
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #pragma once
12 
13 #include <map>
14 #include <memory>
15 #include <mutex>
16 #include <string>
17 #include <vector>
18 
19 namespace eckit {
20 class Parametrisation;
21 }
22 
23 namespace atlas {
24 namespace util {
25 
26 class FactoryBase;
27 
29 protected:
30  FactoryRegistry( const std::string& factory );
31  virtual ~FactoryRegistry();
32 
33 private:
34  mutable std::mutex mutex_;
35  std::string factory_;
36  std::map<std::string, FactoryBase*> factories_;
37 
38 public:
39  const std::string& factory() const { return factory_; }
40  std::vector<std::string> keys() const;
41  void list( std::ostream& ) const;
42  bool has( const std::string& builder ) const;
43  void add( const std::string& builder, FactoryBase* );
44  void remove( const std::string& builder );
45  FactoryBase* get( const std::string& builder ) const;
46 };
47 
48 template <typename T>
50 public:
51  static std::shared_ptr<FactoryRegistryT<T>> instance() {
52  static std::shared_ptr<FactoryRegistryT<T>> env( new FactoryRegistryT<T>( T::className() ) );
53  return env;
54  }
55  virtual ~FactoryRegistryT() {}
56 
57 protected:
58  FactoryRegistryT( const std::string& factory ) : FactoryRegistry( factory ) {}
59 };
60 
61 class FactoryBase {
62 private:
63  FactoryRegistry& registry_;
64  std::string builder_;
65  std::shared_ptr<FactoryRegistry> attached_registry_;
66 
67 protected:
68  FactoryBase( FactoryRegistry&, const std::string& builder );
69  virtual ~FactoryBase();
70  void attach_registry( const std::shared_ptr<FactoryRegistry>& registry ) { attached_registry_ = registry; }
71  friend class FactoryRegistry;
72 
73 public:
74  const std::string& factoryBuilder() const { return builder_; }
75  const std::string& factoryName() const { return registry_.factory(); }
76 };
77 
78 template <typename T>
79 class Factory : public FactoryBase {
80 public:
81  static std::vector<std::string> keys() { return registry().keys(); }
82  static void list( std::ostream& out ) { return registry().list( out ); }
83  static bool has( const std::string& builder ) { return registry().has( builder ); }
84  static T* get( const std::string& builder ) { return dynamic_cast<T*>( registry().get( builder ) ); }
85 
86  Factory( const std::string& builder = "" ) : FactoryBase( registry(), builder ) {
87  if ( not builder.empty() ) {
88  attach_registry( FactoryRegistryT<T>::instance() );
89  }
90  }
91 
92 protected:
93  virtual ~Factory(){};
94  static FactoryRegistry& registry() { return *FactoryRegistryT<T>::instance().get(); }
95 };
96 
97 //----------------------------------------------------------------------------------------------------------------------
98 
99 } // namespace util
100 } // namespace atlas
Definition: Factory.h:79
Definition: Factory.h:61
Definition: Domain.h:19
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
Definition: Factory.h:49
Definition: Factory.h:28