GEOSX
ObjectCatalog.hpp
Go to the documentation of this file.
1 #ifndef GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_
2 #define GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_
3 /*
4  * ------------------------------------------------------------------------------------------------------------
5  * SPDX-License-Identifier: LGPL-2.1-only
6  *
7  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
8  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
9  * Copyright (c) 2018-2020 TotalEnergies
10  * Copyright (c) 2019- GEOSX Contributors
11  * All rights reserved
12  *
13  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
14  * ------------------------------------------------------------------------------------------------------------
15  */
16 
28 #include "common/Logger.hpp"
29 #include "codingUtilities/StringUtilities.hpp"
30 #include "LvArray/src/system.hpp"
31 
32 #include <iostream>
33 #include <list>
34 #include <memory>
35 #include <unordered_map>
36 
37 #ifndef OBJECTCATALOGVERBOSE
41 #define OBJECTCATALOGVERBOSE 0
42 #endif
43 
44 
45 #ifndef BASEHOLDSCATALOG
49 #define BASEHOLDSCATALOG 1
50 #endif
51 
52 namespace geos
53 {
54 namespace dataRepository
55 {
56 
63 //START_SPHINX_0
64 template< typename BASETYPE, typename ... ARGS >
66 {
67 public:
68 
70  //START_SPHINX_1
72  std::unique_ptr< CatalogInterface< BASETYPE, ARGS... > > > CatalogType;
73  //STOP_SPHINX
74 
79  {
80 #if OBJECTCATALOGVERBOSE > 1
81  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
82 #endif
83  }
84 
89  {
90 #if OBJECTCATALOGVERBOSE > 1
91  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
92 #endif
93  }
94 
98  explicit CatalogInterface( CatalogInterface const & ) = default;
99 
104 
110 
116 
122  {
123 #if BASEHOLDSCATALOG == 1
124  return BASETYPE::getCatalog();
125 #else
126  static CatalogType catalog;
127  return catalog;
128 #endif
129  }
130 
136  virtual std::unique_ptr< BASETYPE > allocate( ARGS... args ) const = 0;
137 
143  static bool hasKeyName( std::string const & objectTypeName )
144  {
145  return getCatalog().count( objectTypeName );
146  }
147 
152  static std::list< typename CatalogType::key_type > getKeys()
153  {
154  std::list< typename CatalogType::key_type > keys;
155  for( typename CatalogType::value_type const & pair: getCatalog() )
156  {
157  keys.push_back( pair.first );
158  }
159  auto const cmp = []( string const & a,
160  string const & b ) -> bool
161  {
162  return stringutilities::toLower( a ) < stringutilities::toLower( b );
163  };
164  keys.sort( cmp );
165 
166  return keys;
167  }
168 
177  //START_SPHINX_2
178  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName,
179  ARGS... args )
180  {
181  // We stop the simulation if the product is not found
182  if( !hasKeyName( objectTypeName ) )
183  {
184  std::list< typename CatalogType::key_type > keys = getKeys();
185  string const tmp = stringutilities::join( keys.cbegin(), keys.cend(), ",\n" );
186 
187  string errorMsg = "Could not find keyword \"" + objectTypeName + "\" in this context. ";
188  errorMsg += "Please be sure that all your keywords are properly spelled or that input file parameters have not changed.\n";
189  errorMsg += "All available keys are: [\n" + tmp + "\n]";
190  GEOS_ERROR( errorMsg );
191  }
192 
193  // We also stop the simulation if the builder is not here.
194  CatalogInterface< BASETYPE, ARGS... > const * builder = getCatalog().at( objectTypeName ).get();
195  if( builder == nullptr )
196  {
197  const string errorMsg = "\"" + objectTypeName + "\" could be found. But the builder is invalid.\n";
198  GEOS_ERROR( errorMsg );
199  }
200 
201  return builder->allocate( args ... );
202  }
203  //STOP_SPHINX
204 
215  template< typename TYPE >
216  static TYPE & catalogCast( BASETYPE & object )
217  {
218  std::string const & castedName = TYPE::catalogName();
219  std::string const & objectName = object.getName();
220 
221  if( castedName != objectName )
222  {
223 #if OBJECTCATALOGVERBOSE > 1
224  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
225 #endif
226  }
227 
228  return static_cast< TYPE & >(object);
229  }
230 
231 };
232 
239 //START_SPHINX_3
240 template< typename BASETYPE, typename TYPE, typename ... ARGS >
241 class CatalogEntry final : public CatalogInterface< BASETYPE, ARGS... >
242 {
243 public:
244 
249  CatalogInterface< BASETYPE, ARGS... >()
250  {
251 #if OBJECTCATALOGVERBOSE > 1
252  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
253  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
254  << " , ... >" );
255 #endif
256  }
257 
261  ~CatalogEntry() override
262  {
263 #if OBJECTCATALOGVERBOSE > 1
264  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
265  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
266  << " , ... >" );
267 #endif
268 
269  }
270 
275  CatalogEntry( CatalogEntry const & source ):
276  CatalogInterface< BASETYPE, ARGS... >( source )
277  {}
278 
284  CatalogInterface< BASETYPE, ARGS... >( std::move( source ))
285  {}
286 
292  CatalogEntry & operator=( CatalogEntry const & source )
293  {
295  }
296 
303  {
305  }
306 
312  //START_SPHINX_4
313  virtual std::unique_ptr< BASETYPE > allocate( ARGS... args ) const override
314  {
315 #if OBJECTCATALOGVERBOSE > 0
316  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
317  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
318 #endif
319 #if ( __cplusplus >= 201402L )
320  return std::make_unique< TYPE >( args ... );
321 #else
322  return std::unique_ptr< BASETYPE >( new TYPE( args ... ) );
323 #endif
324  }
325  //STOP_SPHINX
326 
327 };
328 
329 
335 template< typename BASETYPE, typename TYPE, typename ... ARGS >
337 {
338 public:
344  {
345 #if OBJECTCATALOGVERBOSE > 1
346  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
347  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
348  << " , ... >" );
349 #endif
350 
351  std::string name = TYPE::catalogName();
352 #if ( __cplusplus >= 201402L )
353  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE, ARGS... > >();
354 #else
355  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > >( new CatalogEntry< BASETYPE,
356  TYPE,
357  ARGS... >() );
358 #endif
359  ( CatalogInterface< BASETYPE, ARGS... >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
360 
361 #if OBJECTCATALOGVERBOSE > 0
362  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
363  << " catalog component of derived type "
364  << LvArray::system::demangle( typeid(TYPE).name())
365  << " where " << LvArray::system::demangle( typeid(TYPE).name())
366  << "::catalogName() = " << TYPE::catalogName());
367 #endif
368  }
369 
374  {
375 #if OBJECTCATALOGVERBOSE > 1
376  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
377  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
378  << " , ... >" );
379 #endif
380  }
381 
386 
391 
392 
398 
404 
405 };
406 
411 template< typename BASETYPE >
412 class CatalogInterface< BASETYPE >
413 {
414 public:
415 
417  typedef std::unordered_map< std::string, std::unique_ptr< CatalogInterface< BASETYPE > > > CatalogType;
418 
423  {
424 #if OBJECTCATALOGVERBOSE > 1
425  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
426  << " , ... >" );
427 #endif
428  }
429 
434  {
435 #if OBJECTCATALOGVERBOSE > 1
436  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
437  << " , ... >" );
438 #endif
439  }
440 
444  explicit CatalogInterface( CatalogInterface const & ) = default;
445 
450 
456 
462 
468  {
469 #if BASEHOLDSCATALOG == 1
470  return BASETYPE::getCatalog();
471 #else
472  static CatalogType catalog;
473  return catalog;
474 #endif
475  }
476 
481  virtual std::unique_ptr< BASETYPE > allocate( ) const = 0;
482 
488  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName )
489  {
490  CatalogInterface< BASETYPE > const * const entry = getCatalog().at( objectTypeName ).get();
491  return entry->allocate();
492  }
493 
504  template< typename TYPE >
505  static TYPE & catalogCast( BASETYPE & object )
506  {
507  std::string const & castedName = TYPE::catalogName();
508  std::string const & objectName = object.getName();
509 
510  if( castedName != objectName )
511  {
512 #if OBJECTCATALOGVERBOSE > 1
513  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
514 #endif
515  }
516 
517  return static_cast< TYPE & >(object);
518  }
519 
520 };
521 
527 template< typename BASETYPE, typename TYPE >
528 class CatalogEntry< BASETYPE, TYPE > final : public CatalogInterface< BASETYPE >
529 {
530 public:
535  CatalogInterface< BASETYPE >()
536  {
537 #if OBJECTCATALOGVERBOSE > 1
538  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
539  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
540  << " , ... >" );
541 #endif
542  }
543 
547  ~CatalogEntry() override
548  {
549 #if OBJECTCATALOGVERBOSE > 1
550  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
551  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
552  << " , ... >" );
553 #endif
554 
555  }
556 
561  CatalogEntry( CatalogEntry const & source ):
562  CatalogInterface< BASETYPE >( source )
563  {}
564 
570  CatalogInterface< BASETYPE >( std::move( source ))
571  {}
572 
578  CatalogEntry & operator=( CatalogEntry const & source )
579  {
581  }
582 
589  {
590  CatalogInterface< BASETYPE >::operator=( std::move(source));
591  }
592 
597  virtual std::unique_ptr< BASETYPE > allocate( ) const override
598  {
599 #if OBJECTCATALOGVERBOSE > 0
600  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
601  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
602 #endif
603 #if ( __cplusplus >= 201402L )
604  return std::make_unique< TYPE >( );
605 #else
606  return std::unique_ptr< BASETYPE >( new TYPE( ) );
607 #endif
608  }
609 };
610 
611 
615 template< typename BASETYPE, typename TYPE >
616 class CatalogEntryConstructor< BASETYPE, TYPE >
617 {
618 public:
619 
624  {
625 #if OBJECTCATALOGVERBOSE > 1
626  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
627  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
628  << " , ... >" );
629 #endif
630 
631  std::string name = TYPE::catalogName();
632 #if ( __cplusplus >= 201402L )
633  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE > >();
634 #else
635  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE > >( new CatalogEntry< BASETYPE, TYPE >() );
636 #endif
637  ( CatalogInterface< BASETYPE >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
638 
639 #if OBJECTCATALOGVERBOSE > 0
640  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
641  << " catalog component of derived type "
642  << LvArray::system::demangle( typeid(TYPE).name())
643  << " where " << LvArray::system::demangle( typeid(TYPE).name())
644  << "::catalogName() = " << TYPE::catalogName());
645 #endif
646  }
647 
652  {
653 #if OBJECTCATALOGVERBOSE > 1
654  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
655  << " , " << LvArray::system::demangle( typeid(BASETYPE).name()) << " , ... >" );
656 #endif
657  }
658 
663 
668 
674 
680 
681 };
682 
683 
684 }
685 }
686 
687 
699 #define REGISTER_CATALOG_ENTRY( BaseType, DerivedType, ... ) \
700  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType, __VA_ARGS__ > catEntry_ ## DerivedType; }
701 
705 #define REGISTER_CATALOG_ENTRY0( BaseType, DerivedType ) \
706  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType > catEntry_ ## DerivedType; }
707 
708 #endif /* GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_ */
#define GEOS_LOG(...)
Log a message on screen.
Definition: Logger.hpp:39
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:122
Specialization of CatalogEntry for types with no-argument constructors.
CatalogEntry(CatalogEntry &&source)
Move constructor.
virtual std::unique_ptr< BASETYPE > allocate() const override
Create a new instance of TYPE.
CatalogEntry & operator=(CatalogEntry const &source)
Copy assignment operator.
CatalogEntry()
Default constructor.
~CatalogEntry() override
Default destructor.
CatalogEntry & operator=(CatalogEntry &&source)
Move assignment operator.
CatalogEntry(CatalogEntry const &source)
Copy constructor.
CatalogEntryConstructor & operator=(CatalogEntryConstructor &&)=delete
Deleted move assignment operator.
CatalogEntryConstructor & operator=(CatalogEntryConstructor const &)=delete
Deleted copy assignment operator.
CatalogEntryConstructor()
Default constructor.
CatalogEntryConstructor(CatalogEntryConstructor &&)=delete
Deleted move constructor.
~CatalogEntryConstructor()
Default destuctor.
CatalogEntryConstructor(CatalogEntryConstructor const &)=delete
Deleted copy constructor.
A class to generate the catalog entry.
~CatalogEntryConstructor()
Default destructor.
CatalogEntryConstructor(CatalogEntryConstructor const &)=delete
Deleted copy constructor.
CatalogEntryConstructor(CatalogEntryConstructor &&)=delete
Deleted move constructor.
CatalogEntryConstructor()
Constructor creates a catalog entry using the key defined by TYPE::catalogName(), and value of Catalo...
CatalogEntryConstructor & operator=(CatalogEntryConstructor const &)=delete
Deleted copy assignment operator.
CatalogEntryConstructor & operator=(CatalogEntryConstructor &&)=delete
Deleted move assignment operator.
Class to hold allocation capability for specific target derived types.
virtual std::unique_ptr< BASETYPE > allocate(ARGS... args) const override
Create a new object that derives from BASETYPE.
CatalogEntry()
Default constructor.
CatalogEntry(CatalogEntry const &source)
Copy constructor.
CatalogEntry & operator=(CatalogEntry &&source)
Move assignment operator.
CatalogEntry(CatalogEntry &&source)
Move constructor.
CatalogEntry & operator=(CatalogEntry const &source)
Copy assignment operator.
~CatalogEntry() override
Default destructor.
Specialization of CatalogInterface for types with no-argument constructors/.
CatalogInterface(CatalogInterface const &)=default
Copy constructor.
CatalogInterface & operator=(CatalogInterface &&)=default
Move assignment operator.
CatalogInterface(CatalogInterface &&)=default
Move constructor.
std::unordered_map< std::string, std::unique_ptr< CatalogInterface< BASETYPE > > > CatalogType
This is the type that will be used for the catalog. The catalog is actually instantiated in the BASET...
static CatalogType & getCatalog()
Get the catalog from that is stored in the target base class.
CatalogInterface & operator=(CatalogInterface const &)=default
Copy assignment operator.
static std::unique_ptr< BASETYPE > factory(std::string const &objectTypeName)
Create a new object that derives from BASETYPE.
static TYPE & catalogCast(BASETYPE &object)
Downcast base type reference to derived type.
virtual std::unique_ptr< BASETYPE > allocate() const =0
Create a new object that derives from BASETYPE.
This class provides the base class/interface for the catalog value objects.
virtual ~CatalogInterface()
Default destructor.
CatalogInterface(CatalogInterface &&)=default
Move constructor.
static CatalogType & getCatalog()
Get the catalog from that is stored in the target base class.
static std::unique_ptr< BASETYPE > factory(std::string const &objectTypeName, ARGS... args)
Static method to create a new object that derives from BASETYPE.
CatalogInterface & operator=(CatalogInterface &&)=default
Move assignment operator.
static bool hasKeyName(std::string const &objectTypeName)
Check if catalog contains a given key.
virtual std::unique_ptr< BASETYPE > allocate(ARGS... args) const =0
Create a new object that derives from BASETYPE.
static std::list< typename CatalogType::key_type > getKeys()
Returns the product keys of the catalog. Keys are sorted in alphabetical order, case insensitive.
std::unordered_map< std::string, std::unique_ptr< CatalogInterface< BASETYPE, ARGS... > > > CatalogType
This is the type that will be used for the catalog. The catalog is actually instantiated in the BASET...
CatalogInterface & operator=(CatalogInterface const &)=default
Copy assignment operator.
static TYPE & catalogCast(BASETYPE &object)
Downcast base type reference to derived type.
CatalogInterface(CatalogInterface const &)=default
Copy constructor.
std::string string
String type.
Definition: DataTypes.hpp:131
mapBase< TKEY, TVAL, std::integral_constant< bool, false > > unordered_map
Unordered map type.
Definition: DataTypes.hpp:413
void insert(OrderedVariableToManyElementRelation &relation, localIndex const firstIndex, localIndex const er, localIndex const esr, localIndex const ei)
Insert an element relation for an object in the relation.