RINGMesh  Version 5.0.0
A programming library for geological model meshes
factory.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #pragma once
37 
38 #include <ringmesh/basic/common.h>
39 
45 namespace RINGMesh
46 {
60  template < typename Key, typename BaseClass, typename... Args >
61  class Factory
62  {
63  static_assert( std::has_virtual_destructor< BaseClass >::value,
64  "BaseClass must have a virtual destructor" );
65 
66  public:
67  template < typename DerivedClass >
68  static void register_creator( const Key& key )
69  {
70  static_assert( std::is_base_of< BaseClass, DerivedClass >::value,
71  "DerivedClass must be a subclass of BaseClass" );
72  static_assert(
73  std::is_constructible< DerivedClass, Args... >::value,
74  "DerivedClass must be constructible with Args..." );
75  if( !store_
76  .emplace(
77  key, Creator( create_function_impl< DerivedClass > ) )
78  .second )
79  {
81  "Factory", "Trying to register twice the same key" );
82  }
83  }
84 
85  static std::unique_ptr< BaseClass > create(
86  const Key& key, const Args&... args )
87  {
88  auto creator = store_.find( key );
89  if( creator != store_.end() )
90  {
91  return creator->second(
92  std::forward< const Args& >( args )... );
93  }
94  return {};
95  }
96 
97  static std::vector< Key > list_creators()
98  {
99  std::vector< Key > creators;
100  creators.reserve( store_.size() );
101  for( const auto& creator : store_ )
102  {
103  creators.emplace_back( creator.first );
104  }
105  return creators;
106  }
107 
108  static bool has_creator( const Key& key )
109  {
110  return store_.find( key ) != store_.end();
111  }
112 
113  using Creator = typename std::add_pointer< std::unique_ptr< BaseClass >(
114  const Args&... ) >::type;
115  using FactoryStore = std::map< Key, Creator >;
116 
117  private:
118  template < typename DerivedClass >
119  static std::unique_ptr< BaseClass > create_function_impl(
120  Args&&... args )
121  {
122  return std::unique_ptr< BaseClass >{ new DerivedClass{
123  std::forward< Args >( args )... } };
124  }
125 
127  };
128 
129  template < typename Key, typename BaseClass, typename... Args >
130  typename Factory< Key, BaseClass, Args... >::FactoryStore
131  Factory< Key, BaseClass, Args... >::store_;
132 } // namespace RINGMesh
static std::vector< Key > list_creators()
Definition: factory.h:97
std::map< Key, Creator > FactoryStore
Definition: factory.h:115
static std::unique_ptr< BaseClass > create(const Key &key, const Args &... args)
Definition: factory.h:85
static void warn(const std::string &feature, const Args &... args)
Definition: logger.h:75
static bool has_creator(const Key &key)
Definition: factory.h:108
static std::unique_ptr< BaseClass > create_function_impl(Args &&... args)
Definition: factory.h:119
typename std::add_pointer< std::unique_ptr< BaseClass >(const Args &...) >::type Creator
Definition: factory.h:114
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
static FactoryStore store_
Definition: factory.h:126
static void register_creator(const Key &key)
Definition: factory.h:68