GEOS
ObjectCatalog.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
16 #ifndef GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_
17 #define GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_
18 
30 #include "common/logger/Logger.hpp"
32 #include "LvArray/src/system.hpp"
33 #include "DataContext.hpp"
34 
35 #include <iostream>
36 #include <list>
37 #include <memory>
38 #include <unordered_map>
39 
40 #ifndef OBJECTCATALOGVERBOSE
44 #define OBJECTCATALOGVERBOSE 0
45 #endif
46 
47 
48 #ifndef BASEHOLDSCATALOG
52 #define BASEHOLDSCATALOG 1
53 #endif
54 
55 namespace geos
56 {
57 namespace dataRepository
58 {
59 
66 //START_SPHINX_0
67 template< typename BASETYPE, typename ... ARGS >
69 {
70 public:
71 
73  //START_SPHINX_1
75  std::unique_ptr< CatalogInterface< BASETYPE, ARGS... > > > CatalogType;
76  //STOP_SPHINX
77 
82  {
83 #if OBJECTCATALOGVERBOSE > 1
84  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
85 #endif
86  }
87 
92  {
93 #if OBJECTCATALOGVERBOSE > 1
94  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
95 #endif
96  }
97 
101  explicit CatalogInterface( CatalogInterface const & ) = default;
102 
107 
113 
119 
125  {
126 #if BASEHOLDSCATALOG == 1
127  return BASETYPE::getCatalog();
128 #else
129  static CatalogType catalog;
130  return catalog;
131 #endif
132  }
133 
139  virtual std::unique_ptr< BASETYPE > allocate( ARGS... args ) const = 0;
140 
146  static bool hasKeyName( std::string const & objectTypeName )
147  {
148  return getCatalog().count( objectTypeName );
149  }
150 
155  static std::list< typename CatalogType::key_type > getKeys()
156  {
157  std::list< typename CatalogType::key_type > keys;
158  for( typename CatalogType::value_type const & pair: getCatalog() )
159  {
160  keys.push_back( pair.first );
161  }
162  auto const cmp = []( string const & a,
163  string const & b ) -> bool
164  {
165  return stringutilities::toLower( a ) < stringutilities::toLower( b );
166  };
167  keys.sort( cmp );
168 
169  return keys;
170  }
171 
182  //START_SPHINX_2
183  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName,
184  DataContext const & context,
185  ARGS... args )
186  {
187  // We stop the simulation if the type to create is not found
188  GEOS_ERROR_IF( !hasKeyName( objectTypeName ), unknownTypeError( objectTypeName, context, getKeys() ) );
189 
190  // We also stop the simulation if the builder is not here.
191  CatalogInterface< BASETYPE, ARGS... > const * builder = getCatalog().at( objectTypeName ).get();
192  GEOS_ERROR_IF( builder == nullptr,
193  GEOS_FMT( "Type \"{}\" is valid in {}, but the builder is invalid.",
194  objectTypeName, context ) );
195 
196  return builder->allocate( args ... );
197  }
198  //STOP_SPHINX
199 
207  template< typename KEYS_CONTAINER_T >
208  static string unknownTypeError( string const & objectTypeName, DataContext const & context,
209  KEYS_CONTAINER_T const & allowedKeys )
210  {
211  return GEOS_FMT( "The tag \"{}\" is invalid within {}. Please verify the keywords spelling and that "
212  "input file parameters have not changed.\n"
213  "All available tags are: {}\n",
214  objectTypeName, context, stringutilities::join( allowedKeys, ", " ) );
215  }
216 
227  template< typename TYPE >
228  static TYPE & catalogCast( BASETYPE & object )
229  {
230  std::string const & castedName = TYPE::catalogName();
231  std::string const & objectName = object.getName();
232 
233  if( castedName != objectName )
234  {
235 #if OBJECTCATALOGVERBOSE > 1
236  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
237 #endif
238  }
239 
240  return static_cast< TYPE & >(object);
241  }
242 
243 };
244 
251 //START_SPHINX_3
252 template< typename BASETYPE, typename TYPE, typename ... ARGS >
253 class CatalogEntry final : public CatalogInterface< BASETYPE, ARGS... >
254 {
255 public:
256 
261  CatalogInterface< BASETYPE, ARGS... >()
262  {
263 #if OBJECTCATALOGVERBOSE > 1
264  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
265  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
266  << " , ... >" );
267 #endif
268  }
269 
273  ~CatalogEntry() override
274  {
275 #if OBJECTCATALOGVERBOSE > 1
276  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
277  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
278  << " , ... >" );
279 #endif
280 
281  }
282 
287  CatalogEntry( CatalogEntry const & source ):
288  CatalogInterface< BASETYPE, ARGS... >( source )
289  {}
290 
296  CatalogInterface< BASETYPE, ARGS... >( std::move( source ))
297  {}
298 
304  CatalogEntry & operator=( CatalogEntry const & source )
305  {
307  }
308 
315  {
317  }
318 
324  //START_SPHINX_4
325  virtual std::unique_ptr< BASETYPE > allocate( ARGS ... args ) const override
326  {
327 #if OBJECTCATALOGVERBOSE > 0
328  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
329  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
330 #endif
331 #if ( __cplusplus >= 201402L )
332  return std::make_unique< TYPE >( args ... );
333 #else
334  return std::unique_ptr< BASETYPE >( new TYPE( args ... ) );
335 #endif
336  }
337  //STOP_SPHINX
338 
339 };
340 
341 
347 template< typename BASETYPE, typename TYPE, typename ... ARGS >
349 {
350 public:
356  {
357 #if OBJECTCATALOGVERBOSE > 1
358  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
359  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
360  << " , ... >" );
361 #endif
362 
363  std::string name = TYPE::catalogName();
364 #if ( __cplusplus >= 201402L )
365  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE, ARGS... > >();
366 #else
367  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > >( new CatalogEntry< BASETYPE,
368  TYPE,
369  ARGS... >() );
370 #endif
371  ( CatalogInterface< BASETYPE, ARGS... >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
372 
373 #if OBJECTCATALOGVERBOSE > 0
374  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
375  << " catalog component of derived type "
376  << LvArray::system::demangle( typeid(TYPE).name())
377  << " where " << LvArray::system::demangle( typeid(TYPE).name())
378  << "::catalogName() = " << TYPE::catalogName());
379 #endif
380  }
381 
386  {
387 #if OBJECTCATALOGVERBOSE > 1
388  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
389  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
390  << " , ... >" );
391 #endif
392  }
393 
398 
403 
404 
410 
416 
417 };
418 
423 template< typename BASETYPE >
424 class CatalogInterface< BASETYPE >
425 {
426 public:
427 
429  typedef std::unordered_map< std::string, std::unique_ptr< CatalogInterface< BASETYPE > > > CatalogType;
430 
435  {
436 #if OBJECTCATALOGVERBOSE > 1
437  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
438  << " , ... >" );
439 #endif
440  }
441 
446  {
447 #if OBJECTCATALOGVERBOSE > 1
448  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
449  << " , ... >" );
450 #endif
451  }
452 
456  explicit CatalogInterface( CatalogInterface const & ) = default;
457 
462 
468 
474 
480  {
481 #if BASEHOLDSCATALOG == 1
482  return BASETYPE::getCatalog();
483 #else
484  static CatalogType catalog;
485  return catalog;
486 #endif
487  }
488 
493  virtual std::unique_ptr< BASETYPE > allocate( ) const = 0;
494 
500  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName )
501  {
502  CatalogInterface< BASETYPE > const * const entry = getCatalog().at( objectTypeName ).get();
503  return entry->allocate();
504  }
505 
516  template< typename TYPE >
517  static TYPE & catalogCast( BASETYPE & object )
518  {
519  std::string const & castedName = TYPE::catalogName();
520  std::string const & objectName = object.getName();
521 
522  if( castedName != objectName )
523  {
524 #if OBJECTCATALOGVERBOSE > 1
525  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
526 #endif
527  }
528 
529  return static_cast< TYPE & >(object);
530  }
531 
532 };
533 
539 template< typename BASETYPE, typename TYPE >
540 class CatalogEntry< BASETYPE, TYPE > final : public CatalogInterface< BASETYPE >
541 {
542 public:
547  CatalogInterface< BASETYPE >()
548  {
549 #if OBJECTCATALOGVERBOSE > 1
550  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
551  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
552  << " , ... >" );
553 #endif
554  }
555 
559  ~CatalogEntry() override
560  {
561 #if OBJECTCATALOGVERBOSE > 1
562  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
563  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
564  << " , ... >" );
565 #endif
566 
567  }
568 
573  CatalogEntry( CatalogEntry const & source ):
574  CatalogInterface< BASETYPE >( source )
575  {}
576 
582  CatalogInterface< BASETYPE >( std::move( source ))
583  {}
584 
590  CatalogEntry & operator=( CatalogEntry const & source )
591  {
593  }
594 
601  {
602  CatalogInterface< BASETYPE >::operator=( std::move( source ));
603  }
604 
609  virtual std::unique_ptr< BASETYPE > allocate( ) const override
610  {
611 #if OBJECTCATALOGVERBOSE > 0
612  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
613  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
614 #endif
615 #if ( __cplusplus >= 201402L )
616  return std::make_unique< TYPE >( );
617 #else
618  return std::unique_ptr< BASETYPE >( new TYPE( ) );
619 #endif
620  }
621 };
622 
623 
627 template< typename BASETYPE, typename TYPE >
628 class CatalogEntryConstructor< BASETYPE, TYPE >
629 {
630 public:
631 
636  {
637 #if OBJECTCATALOGVERBOSE > 1
638  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
639  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
640  << " , ... >" );
641 #endif
642 
643  std::string name = TYPE::catalogName();
644 #if ( __cplusplus >= 201402L )
645  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE > >();
646 #else
647  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE > >( new CatalogEntry< BASETYPE, TYPE >() );
648 #endif
649  ( CatalogInterface< BASETYPE >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
650 
651 #if OBJECTCATALOGVERBOSE > 0
652  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
653  << " catalog component of derived type "
654  << LvArray::system::demangle( typeid(TYPE).name())
655  << " where " << LvArray::system::demangle( typeid(TYPE).name())
656  << "::catalogName() = " << TYPE::catalogName());
657 #endif
658  }
659 
664  {
665 #if OBJECTCATALOGVERBOSE > 1
666  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
667  << " , " << LvArray::system::demangle( typeid(BASETYPE).name()) << " , ... >" );
668 #endif
669  }
670 
675 
680 
686 
692 
693 };
694 
695 
696 }
697 }
698 
699 
711 #define REGISTER_CATALOG_ENTRY( BaseType, DerivedType, ... ) \
712  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType, __VA_ARGS__ > catEntry_ ## DerivedType; }
713 
717 #define REGISTER_CATALOG_ENTRY0( BaseType, DerivedType ) \
718  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType > catEntry_ ## DerivedType; }
719 
720 #endif /* GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_ */
#define GEOS_LOG(...)
Log a message on screen.
Definition: Logger.hpp:40
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:142
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.
static std::unique_ptr< BASETYPE > factory(std::string const &objectTypeName, DataContext const &context, ARGS... args)
Static method to create a new object that derives from BASETYPE.
CatalogInterface(CatalogInterface &&)=default
Move constructor.
static CatalogType & getCatalog()
Get the catalog from that is stored in the target base class.
CatalogInterface & operator=(CatalogInterface &&)=default
Move assignment operator.
static string unknownTypeError(string const &objectTypeName, DataContext const &context, KEYS_CONTAINER_T const &allowedKeys)
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:91
mapBase< TKEY, TVAL, std::integral_constant< bool, false > > unordered_map
Unordered map type.
Definition: DataTypes.hpp:373
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.