Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:49

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file corecel/sys/Environment.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <functional>
0011 #include <iosfwd>
0012 #include <string>
0013 #include <unordered_map>
0014 #include <utility>
0015 #include <vector>
0016 
0017 namespace celeritas
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Interrogate and extend environment variables.
0022  *
0023  * This makes it easier to generate reproducible runs, launch Celeritas
0024  * remotely, or integrate with application drivers. The environment variables
0025  * may be encoded as JSON input to supplement or override system environment
0026  * variables, or set programmatically via this API call. Later the environment
0027  * class can be interrogated to find which environment variables were accessed.
0028  *
0029  * Unlike the standard environment which returns a null pointer for an *unset*
0030  * variable, this returns an empty string.
0031  *
0032  * \note This class is not thread-safe on its own. The \c celeritas::getenv
0033  * free function however is safe, although it should only be used in setup
0034  * (single-thread) steps.
0035  *
0036  * \note Once inserted into the environment map, values cannot be changed.
0037  * Standard practice in the code is to evaluate the environment variable
0038  * exactly \em once and cache the result as a static const variable. If you
0039  * really wanted to, you could call <code> celeritas::environment() = {};
0040  * </code> but that could result in the end-of-run diagnostic reporting
0041  * different values than the ones actually used during the code's setup.
0042  */
0043 class Environment
0044 {
0045   private:
0046     using Container = std::unordered_map<std::string, std::string>;
0047 
0048   public:
0049     //!@{
0050     //! \name Type aliases
0051     using key_type = Container::key_type;
0052     using mapped_type = Container::mapped_type;
0053     using value_type = Container::value_type;
0054     using const_iterator = Container::const_iterator;
0055     using VecKVRef = std::vector<std::reference_wrapper<value_type>>;
0056     //!@}
0057 
0058   public:
0059     // Construct with defaults
0060     Environment() = default;
0061 
0062     // Get an environment variable from current or system environments
0063     inline mapped_type const& operator[](key_type const&);
0064 
0065     // Insert possibly new environment variables
0066     bool insert(value_type const& value);
0067 
0068     //! Get an ordered (by access) vector of key/value pairs
0069     VecKVRef const& ordered_environment() const { return ordered_; }
0070 
0071     // Remove all entries
0072     void clear();
0073 
0074     // Insert (not overriding!) from another environment
0075     void merge(Environment const& other);
0076 
0077   private:
0078     std::unordered_map<key_type, mapped_type> vars_;
0079     VecKVRef ordered_;
0080 
0081     mapped_type const& load_from_getenv(key_type const&);
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 //! Return result from \c getenv_flag
0086 struct GetenvFlagResult
0087 {
0088     bool value{};  //!< Determined by user or default
0089     bool defaulted{};  //!< True if no valid user value was present
0090 };
0091 
0092 //---------------------------------------------------------------------------//
0093 // FREE FUNCTIONS
0094 //---------------------------------------------------------------------------//
0095 
0096 // Access a static global environment variable
0097 Environment& environment();
0098 
0099 // Thread-safe access to environment variables
0100 std::string const& getenv(std::string const& key);
0101 
0102 // Thread-safe flag access to environment variables
0103 GetenvFlagResult getenv_flag(std::string const& key, bool default_val);
0104 
0105 // Write the accessed environment variables to a stream
0106 std::ostream& operator<<(std::ostream&, Environment const&);
0107 
0108 //---------------------------------------------------------------------------//
0109 // INLINE DEFINITIONS
0110 //---------------------------------------------------------------------------//
0111 /*!
0112  * Get an environment variable from current or system enviroments.
0113  */
0114 auto Environment::operator[](key_type const& env_var) -> mapped_type const&
0115 {
0116     auto iter = vars_.find(env_var);
0117     if (iter == vars_.end())
0118     {
0119         return this->load_from_getenv(env_var);
0120     }
0121     return iter->second;
0122 }
0123 
0124 //---------------------------------------------------------------------------//
0125 }  // namespace celeritas