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 
34 #include <iostream>
35 #include <list>
36 #include <memory>
37 #include <unordered_map>
38 
39 #ifndef OBJECTCATALOGVERBOSE
43 #define OBJECTCATALOGVERBOSE 0
44 #endif
45 
46 
47 #ifndef BASEHOLDSCATALOG
51 #define BASEHOLDSCATALOG 1
52 #endif
53 
54 namespace geos
55 {
56 namespace dataRepository
57 {
58 
65 //START_SPHINX_0
66 template< typename BASETYPE, typename ... ARGS >
68 {
69 public:
70 
72  //START_SPHINX_1
74  std::unique_ptr< CatalogInterface< BASETYPE, ARGS... > > > CatalogType;
75  //STOP_SPHINX
76 
81  {
82 #if OBJECTCATALOGVERBOSE > 1
83  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
84 #endif
85  }
86 
91  {
92 #if OBJECTCATALOGVERBOSE > 1
93  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid( BASETYPE ).name() ) << " , ... >" );
94 #endif
95  }
96 
100  explicit CatalogInterface( CatalogInterface const & ) = default;
101 
106 
112 
118 
124  {
125 #if BASEHOLDSCATALOG == 1
126  return BASETYPE::getCatalog();
127 #else
128  static CatalogType catalog;
129  return catalog;
130 #endif
131  }
132 
138  virtual std::unique_ptr< BASETYPE > allocate( ARGS... args ) const = 0;
139 
145  static bool hasKeyName( std::string const & objectTypeName )
146  {
147  return getCatalog().count( objectTypeName );
148  }
149 
154  static std::list< typename CatalogType::key_type > getKeys()
155  {
156  std::list< typename CatalogType::key_type > keys;
157  for( typename CatalogType::value_type const & pair: getCatalog() )
158  {
159  keys.push_back( pair.first );
160  }
161  auto const cmp = []( string const & a,
162  string const & b ) -> bool
163  {
164  return stringutilities::toLower( a ) < stringutilities::toLower( b );
165  };
166  keys.sort( cmp );
167 
168  return keys;
169  }
170 
179  //START_SPHINX_2
180  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName,
181  ARGS... args )
182  {
183  // We stop the simulation if the product is not found
184  if( !hasKeyName( objectTypeName ) )
185  {
186  std::list< typename CatalogType::key_type > keys = getKeys();
187  string const tmp = stringutilities::join( keys.cbegin(), keys.cend(), ",\n" );
188 
189  string errorMsg = "Could not find keyword \"" + objectTypeName + "\" in this context. ";
190  errorMsg += "Please be sure that all your keywords are properly spelled or that input file parameters have not changed.\n";
191  errorMsg += "All available keys are: [\n" + tmp + "\n]";
192  GEOS_ERROR( errorMsg );
193  }
194 
195  // We also stop the simulation if the builder is not here.
196  CatalogInterface< BASETYPE, ARGS... > const * builder = getCatalog().at( objectTypeName ).get();
197  if( builder == nullptr )
198  {
199  const string errorMsg = "\"" + objectTypeName + "\" could be found. But the builder is invalid.\n";
200  GEOS_ERROR( errorMsg );
201  }
202 
203  return builder->allocate( args ... );
204  }
205  //STOP_SPHINX
206 
217  template< typename TYPE >
218  static TYPE & catalogCast( BASETYPE & object )
219  {
220  std::string const & castedName = TYPE::catalogName();
221  std::string const & objectName = object.getName();
222 
223  if( castedName != objectName )
224  {
225 #if OBJECTCATALOGVERBOSE > 1
226  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
227 #endif
228  }
229 
230  return static_cast< TYPE & >(object);
231  }
232 
233 };
234 
241 //START_SPHINX_3
242 template< typename BASETYPE, typename TYPE, typename ... ARGS >
243 class CatalogEntry final : public CatalogInterface< BASETYPE, ARGS... >
244 {
245 public:
246 
251  CatalogInterface< BASETYPE, ARGS... >()
252  {
253 #if OBJECTCATALOGVERBOSE > 1
254  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
255  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
256  << " , ... >" );
257 #endif
258  }
259 
263  ~CatalogEntry() override
264  {
265 #if OBJECTCATALOGVERBOSE > 1
266  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
267  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
268  << " , ... >" );
269 #endif
270 
271  }
272 
277  CatalogEntry( CatalogEntry const & source ):
278  CatalogInterface< BASETYPE, ARGS... >( source )
279  {}
280 
286  CatalogInterface< BASETYPE, ARGS... >( std::move( source ))
287  {}
288 
294  CatalogEntry & operator=( CatalogEntry const & source )
295  {
297  }
298 
305  {
307  }
308 
314  //START_SPHINX_4
315  virtual std::unique_ptr< BASETYPE > allocate( ARGS... args ) const override
316  {
317 #if OBJECTCATALOGVERBOSE > 0
318  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
319  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
320 #endif
321 #if ( __cplusplus >= 201402L )
322  return std::make_unique< TYPE >( args ... );
323 #else
324  return std::unique_ptr< BASETYPE >( new TYPE( args ... ) );
325 #endif
326  }
327  //STOP_SPHINX
328 
329 };
330 
331 
337 template< typename BASETYPE, typename TYPE, typename ... ARGS >
339 {
340 public:
346  {
347 #if OBJECTCATALOGVERBOSE > 1
348  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
349  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
350  << " , ... >" );
351 #endif
352 
353  std::string name = TYPE::catalogName();
354 #if ( __cplusplus >= 201402L )
355  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE, ARGS... > >();
356 #else
357  std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE, ARGS... > >( new CatalogEntry< BASETYPE,
358  TYPE,
359  ARGS... >() );
360 #endif
361  ( CatalogInterface< BASETYPE, ARGS... >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
362 
363 #if OBJECTCATALOGVERBOSE > 0
364  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
365  << " catalog component of derived type "
366  << LvArray::system::demangle( typeid(TYPE).name())
367  << " where " << LvArray::system::demangle( typeid(TYPE).name())
368  << "::catalogName() = " << TYPE::catalogName());
369 #endif
370  }
371 
376  {
377 #if OBJECTCATALOGVERBOSE > 1
378  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
379  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
380  << " , ... >" );
381 #endif
382  }
383 
388 
393 
394 
400 
406 
407 };
408 
413 template< typename BASETYPE >
414 class CatalogInterface< BASETYPE >
415 {
416 public:
417 
419  typedef std::unordered_map< std::string, std::unique_ptr< CatalogInterface< BASETYPE > > > CatalogType;
420 
425  {
426 #if OBJECTCATALOGVERBOSE > 1
427  GEOS_LOG( "Calling constructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
428  << " , ... >" );
429 #endif
430  }
431 
436  {
437 #if OBJECTCATALOGVERBOSE > 1
438  GEOS_LOG( "Calling destructor for CatalogInterface< " << LvArray::system::demangle( typeid(BASETYPE).name())
439  << " , ... >" );
440 #endif
441  }
442 
446  explicit CatalogInterface( CatalogInterface const & ) = default;
447 
452 
458 
464 
470  {
471 #if BASEHOLDSCATALOG == 1
472  return BASETYPE::getCatalog();
473 #else
474  static CatalogType catalog;
475  return catalog;
476 #endif
477  }
478 
483  virtual std::unique_ptr< BASETYPE > allocate( ) const = 0;
484 
490  static std::unique_ptr< BASETYPE > factory( std::string const & objectTypeName )
491  {
492  CatalogInterface< BASETYPE > const * const entry = getCatalog().at( objectTypeName ).get();
493  return entry->allocate();
494  }
495 
506  template< typename TYPE >
507  static TYPE & catalogCast( BASETYPE & object )
508  {
509  std::string const & castedName = TYPE::catalogName();
510  std::string const & objectName = object.getName();
511 
512  if( castedName != objectName )
513  {
514 #if OBJECTCATALOGVERBOSE > 1
515  GEOS_LOG( "Invalid Cast of " << objectName << " to " << castedName );
516 #endif
517  }
518 
519  return static_cast< TYPE & >(object);
520  }
521 
522 };
523 
529 template< typename BASETYPE, typename TYPE >
530 class CatalogEntry< BASETYPE, TYPE > final : public CatalogInterface< BASETYPE >
531 {
532 public:
537  CatalogInterface< BASETYPE >()
538  {
539 #if OBJECTCATALOGVERBOSE > 1
540  GEOS_LOG( "Calling constructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
541  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
542  << " , ... >" );
543 #endif
544  }
545 
549  ~CatalogEntry() override
550  {
551 #if OBJECTCATALOGVERBOSE > 1
552  GEOS_LOG( "Calling destructor for CatalogEntry< " << LvArray::system::demangle( typeid(TYPE).name())
553  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
554  << " , ... >" );
555 #endif
556 
557  }
558 
563  CatalogEntry( CatalogEntry const & source ):
564  CatalogInterface< BASETYPE >( source )
565  {}
566 
572  CatalogInterface< BASETYPE >( std::move( source ))
573  {}
574 
580  CatalogEntry & operator=( CatalogEntry const & source )
581  {
583  }
584 
591  {
592  CatalogInterface< BASETYPE >::operator=( std::move(source));
593  }
594 
599  virtual std::unique_ptr< BASETYPE > allocate( ) const override
600  {
601 #if OBJECTCATALOGVERBOSE > 0
602  GEOS_LOG( "Creating type " << LvArray::system::demangle( typeid(TYPE).name())
603  << " from catalog of " << LvArray::system::demangle( typeid(BASETYPE).name()));
604 #endif
605 #if ( __cplusplus >= 201402L )
606  return std::make_unique< TYPE >( );
607 #else
608  return std::unique_ptr< BASETYPE >( new TYPE( ) );
609 #endif
610  }
611 };
612 
613 
617 template< typename BASETYPE, typename TYPE >
618 class CatalogEntryConstructor< BASETYPE, TYPE >
619 {
620 public:
621 
626  {
627 #if OBJECTCATALOGVERBOSE > 1
628  GEOS_LOG( "Calling constructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
629  << " , " << LvArray::system::demangle( typeid(BASETYPE).name())
630  << " , ... >" );
631 #endif
632 
633  std::string name = TYPE::catalogName();
634 #if ( __cplusplus >= 201402L )
635  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::make_unique< CatalogEntry< BASETYPE, TYPE > >();
636 #else
637  std::unique_ptr< CatalogEntry< BASETYPE, TYPE > > temp = std::unique_ptr< CatalogEntry< BASETYPE, TYPE > >( new CatalogEntry< BASETYPE, TYPE >() );
638 #endif
639  ( CatalogInterface< BASETYPE >::getCatalog() ).insert( std::move( std::make_pair( name, std::move( temp ) ) ) );
640 
641 #if OBJECTCATALOGVERBOSE > 0
642  GEOS_LOG( "Registered " << LvArray::system::demangle( typeid(BASETYPE).name())
643  << " catalog component of derived type "
644  << LvArray::system::demangle( typeid(TYPE).name())
645  << " where " << LvArray::system::demangle( typeid(TYPE).name())
646  << "::catalogName() = " << TYPE::catalogName());
647 #endif
648  }
649 
654  {
655 #if OBJECTCATALOGVERBOSE > 1
656  GEOS_LOG( "Calling destructor for CatalogEntryConstructor< " << LvArray::system::demangle( typeid(TYPE).name())
657  << " , " << LvArray::system::demangle( typeid(BASETYPE).name()) << " , ... >" );
658 #endif
659  }
660 
665 
670 
676 
682 
683 };
684 
685 
686 }
687 }
688 
689 
701 #define REGISTER_CATALOG_ENTRY( BaseType, DerivedType, ... ) \
702  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType, __VA_ARGS__ > catEntry_ ## DerivedType; }
703 
707 #define REGISTER_CATALOG_ENTRY0( BaseType, DerivedType ) \
708  namespace { GEOS_MAYBE_UNUSED geos::dataRepository::CatalogEntryConstructor< BaseType, DerivedType > catEntry_ ## DerivedType; }
709 
710 #endif /* GEOS_DATAREPOSITORY_OBJECTCATALOG_HPP_ */
#define GEOS_LOG(...)
Log a message on screen.
Definition: Logger.hpp:40
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:157
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: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.