Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:09

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