Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:14

0001 // Copyright (c) 2016 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 
0007 #ifndef BOOST_PROCESS_ENVIRONMENT_HPP_
0008 #define BOOST_PROCESS_ENVIRONMENT_HPP_
0009 
0010 #include <boost/process/detail/config.hpp>
0011 #include <boost/algorithm/string/split.hpp>
0012 #include <boost/algorithm/string/case_conv.hpp>
0013 #include <boost/iterator/transform_iterator.hpp>
0014 #include <boost/process/filesystem.hpp>
0015 
0016 #if defined(BOOST_POSIX_API)
0017 #include <boost/process/detail/posix/environment.hpp>
0018 #elif defined(BOOST_WINDOWS_API)
0019 #include <boost/process/detail/windows/environment.hpp>
0020 #endif
0021 
0022 namespace boost { namespace process {
0023 
0024 namespace detail {
0025 
0026 template<typename Char, typename Environment>
0027 struct const_entry
0028 {
0029     using value_type    = Char ;
0030     using pointer       = const value_type * ;
0031     using string_type   = std::basic_string<value_type> ;
0032     using range         = boost::iterator_range<pointer> ;
0033     using environment_t = Environment ;
0034 
0035     std::vector<string_type> to_vector() const
0036     {
0037         if (_data == nullptr)
0038             return std::vector<string_type>();
0039         std::vector<string_type> data;
0040         auto str = string_type(_data);
0041         struct splitter
0042         {
0043             bool operator()(wchar_t w) const {return w == api::env_seperator<wchar_t>();}
0044             bool operator()(char c)    const {return c == api::env_seperator<char>   ();}
0045         } s;
0046         boost::split(data, _data, s);
0047         return data;
0048     }
0049     string_type to_string()              const
0050     {
0051         if (_data != nullptr)
0052             return string_type(_data);
0053         else
0054             return string_type();
0055     }
0056     string_type get_name() const {return string_type(_name.begin(), _name.end());}
0057     explicit const_entry(string_type&& name, pointer data, environment_t & env_) :
0058         _name(std::move(name)), _data(data), _env(&env_) {}
0059 
0060     explicit const_entry(string_type &&name, environment_t & env) :
0061         _name(std::move(name)), _data(nullptr), _env(&env) {}
0062     const_entry(const const_entry&) = default;
0063     const_entry& operator=(const const_entry&) = default;
0064 
0065     void reload()
0066     {
0067         auto p = _env->find(_name);
0068         if (p == _env->end())
0069             _data = nullptr;
0070         else
0071             _data = p->_data;
0072         this->_env->reload();
0073 
0074     }
0075     bool empty() const
0076     {
0077         return _data == nullptr;
0078     }
0079 protected:
0080     string_type _name;
0081     pointer _data;
0082     environment_t * _env;
0083 };
0084 
0085 template<typename Char, typename Environment>
0086 struct entry : const_entry<Char, Environment>
0087 {
0088     using father = const_entry<Char, Environment>;
0089     using value_type    = typename father::value_type;
0090     using string_type   = typename father::string_type;
0091     using pointer       = typename father::pointer;
0092     using environment_t = typename father::environment_t;
0093 
0094     explicit entry(string_type&& name, pointer data, environment_t & env) :
0095         father(std::move(name), data, env) {}
0096 
0097     explicit entry(string_type &&name, environment_t & env_) :
0098         father(std::move(name), env_) {}
0099 
0100     entry(const entry&) = default;
0101     entry& operator=(const entry&) = default;
0102 
0103     void assign(const string_type &value)
0104     {
0105         this->_env->set(this->_name, value);
0106         this->reload();
0107     }
0108     void assign(const std::vector<string_type> &value)
0109     {
0110         string_type data;
0111         for (auto &v : value)
0112         {
0113             if (&v != &value.front())
0114                 data += api::env_seperator<value_type>();
0115             data += v;
0116         }
0117         this->_env->set(this->_name, data);
0118         this->reload();
0119 
0120     }
0121     void assign(const std::initializer_list<string_type> &value)
0122     {
0123         string_type data;
0124         for (auto &v : value)
0125         {
0126             if (&v != &*value.begin())
0127                 data += api::env_seperator<value_type>();
0128             data += v;
0129         }
0130         this->_env->set(this->_name, data);
0131         this->reload();
0132 
0133     }
0134     void append(const string_type &value)
0135     {
0136         if (this->_data == nullptr)
0137             this->_env->set(this->_name, value);
0138         else
0139         {
0140             string_type st = this->_data;
0141             this->_env->set(this->_name, st + api::env_seperator<value_type>() + value);
0142         }
0143 
0144 
0145         this->reload();
0146 
0147     }
0148     void clear()
0149     {
0150         this->_env->reset(this->_name);
0151         this->_env->reload();
0152         this->_data = nullptr;
0153     }
0154     entry &operator=(const string_type & value)
0155     {
0156         assign(value);
0157         return *this;
0158     }
0159     entry &operator=(const std::vector<string_type> & value)
0160     {
0161         assign(value);
0162         return *this;
0163     }
0164     entry &operator=(const std::initializer_list<string_type> & value)
0165     {
0166         assign(value);
0167         return *this;
0168     }
0169     entry &operator+=(const string_type & value)
0170     {
0171         append(value);
0172         return *this;
0173     }
0174 
0175 };
0176 
0177 
0178 
0179 template<typename Char, typename Environment>
0180 struct make_entry
0181 {
0182 
0183     make_entry(const make_entry&) = default;
0184     make_entry& operator=(const make_entry&) = default;
0185 
0186     Environment *env;
0187     make_entry(Environment & env) : env(&env) {};
0188     entry<Char, Environment> operator()(const Char* data) const
0189     {
0190         auto p = data;
0191         while ((*p != equal_sign<Char>()) && (*p != null_char<Char>()))
0192                 p++;
0193         auto name = std::basic_string<Char>(data, p);
0194         p++; //go behind equal sign
0195 
0196         return entry<Char, Environment>(std::move(name), p, *env);
0197     }
0198 };
0199 
0200 template<typename Char, typename Environment>
0201 struct make_const_entry
0202 {
0203 
0204     make_const_entry(const make_const_entry&) = default;
0205     make_const_entry& operator=(const make_const_entry&) = default;
0206 
0207     Environment *env;
0208     make_const_entry(Environment & env) : env(&env) {};
0209     const_entry<Char, Environment> operator()(const Char* data) const
0210     {
0211         auto p = data;
0212         while ((*p != equal_sign<Char>()) && (*p != null_char<Char>()))
0213                 p++;
0214         auto name = std::basic_string<Char>(data, p);
0215         p++; //go behind equal sign
0216 
0217         return const_entry<Char, Environment>(std::move(name), p, *env);
0218     }
0219 };
0220 
0221 }
0222 
0223 #if !defined (BOOST_PROCESS_DOXYGEN)
0224 
0225 template<typename Char, template <class> class Implementation = detail::api::basic_environment_impl>
0226 class basic_environment_impl : public Implementation<Char>
0227 {
0228     Char** _get_end() const
0229     {
0230         auto p = this->_env_impl;
0231         while (*p != nullptr)
0232             p++;
0233 
0234         return p;
0235     }
0236 public:
0237     using string_type = std::basic_string<Char>;
0238     using implementation_type = Implementation<Char>;
0239     using base_type = basic_environment_impl<Char, Implementation>;
0240     using       entry_maker = detail::make_entry<Char, base_type>;
0241     using entry_type        = detail::entry     <Char, base_type>;
0242     using const_entry_type  = detail::const_entry     <Char, const base_type>;
0243     using const_entry_maker = detail::make_const_entry<Char, const base_type>;
0244 
0245     friend       entry_type;
0246     friend const_entry_type;
0247 
0248     using iterator        = boost::transform_iterator<      entry_maker, Char**,       entry_type,       entry_type>;
0249     using const_iterator  = boost::transform_iterator<const_entry_maker, Char**, const_entry_type, const_entry_type>;
0250     using size_type       = std::size_t;
0251 
0252     iterator        begin()       {return       iterator(this->_env_impl,       entry_maker(*this));}
0253     const_iterator  begin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));}
0254     const_iterator cbegin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));}
0255 
0256     iterator        end()       {return       iterator(_get_end(),       entry_maker(*this));}
0257     const_iterator  end() const {return const_iterator(_get_end(), const_entry_maker(*this));}
0258     const_iterator cend() const {return const_iterator(_get_end(), const_entry_maker(*this));}
0259 
0260     iterator        find( const string_type& key )
0261     {
0262         auto p = this->_env_impl;
0263         auto st1 = key + ::boost::process::detail::equal_sign<Char>();
0264         while (*p != nullptr)
0265         {
0266             const std::size_t len = std::char_traits<Char>::length(*p);
0267             if ((std::distance(st1.begin(), st1.end()) < len)
0268                  && std::equal(st1.begin(), st1.end(), *p))
0269                 break;
0270             p++;
0271         }
0272         return iterator(p, entry_maker(*this));
0273     }
0274     const_iterator  find( const string_type& key ) const
0275     {
0276         auto p = this->_env_impl;
0277         auto st1 = key + ::boost::process::detail::equal_sign<Char>();
0278         while (*p != nullptr)
0279         {
0280             const std::size_t len = std::char_traits<Char>::length(*p);
0281             if ((std::distance(st1.begin(), st1.end()) < len)
0282                 && std::equal(st1.begin(), st1.end(), *p))
0283                 break;
0284             p++;
0285         }
0286         return const_iterator(p, const_entry_maker(*this));
0287     }
0288 
0289     std::size_t count(const string_type & st) const
0290     {
0291         auto p = this->_env_impl;
0292         auto st1 = st + ::boost::process::detail::equal_sign<Char>();
0293         while (*p != nullptr)
0294         {
0295             const std::size_t len = std::char_traits<Char>::length(*p);
0296             if ((std::distance(st1.begin(), st1.end()) <
0297                  static_cast<typename string_type::iterator::difference_type>(len))
0298                 && std::equal(st1.begin(), st1.end(), *p))
0299                 return 1u;
0300             p++;
0301         }
0302         return 0u;
0303     }
0304     void erase(const string_type & id)
0305     {
0306         implementation_type::reset(id);
0307         this->reload();
0308     }
0309     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value)
0310     {
0311         auto f = find(id);
0312         if (f == end())
0313         {
0314             implementation_type::set(id, value);
0315             this->reload();
0316             return std::pair<iterator, bool>(find(id), true);
0317         }
0318         else
0319             return std::pair<iterator, bool>(f, false);
0320     }
0321     using implementation_type::implementation_type;
0322     using implementation_type::operator=;
0323     using native_handle_type = typename implementation_type::native_handle_type;
0324     using implementation_type::native_handle;
0325     //copy ctor if impl is copy-constructible
0326     bool empty()
0327     {
0328         return *this->_env_impl == nullptr;
0329     }
0330     std::size_t size() const
0331     {
0332         return (_get_end() - this->_env_impl);
0333     }
0334     void clear()
0335     {
0336         std::vector<string_type> names;
0337         names.resize(size());
0338         std::transform(cbegin(), cend(), names.begin(), [](const const_entry_type & cet){return cet.get_name();});
0339 
0340         for (auto & nm : names)
0341             implementation_type::reset(nm);
0342 
0343         this->reload();
0344     }
0345 
0346     entry_type  at( const string_type& key )
0347     {
0348         auto f = find(key);
0349         if (f== end())
0350             throw std::out_of_range(key + " not found");
0351         return *f;
0352     }
0353     const_entry_type at( const string_type& key ) const
0354     {
0355         auto f = find(key);
0356         if (f== end())
0357             throw std::out_of_range(key + " not found");
0358         return *f;
0359     }
0360     entry_type operator[](const string_type & key)
0361     {
0362         auto p = find(key);
0363         if (p != end())
0364             return *p;
0365 
0366         return entry_type(string_type(key), *this);
0367     }
0368 };
0369 #endif
0370 
0371 #if defined(BOOST_PROCESS_DOXYGEN)
0372 /**Template representation of environments. It takes a character type (`char` or `wchar_t`)
0373  * as template parameter to implement the environment
0374  */
0375 template<typename Char>
0376 class basic_environment
0377 {
0378 
0379 public:
0380     typedef std::basic_string<Char> string_type;
0381     typedef boost::transform_iterator<      entry_maker, Char**> iterator       ;
0382     typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
0383     typedef std::size_t                                             size_type      ;
0384 
0385     iterator       begin()        ; ///<Returns an iterator to the beginning
0386     const_iterator begin()  const ; ///<Returns an iterator to the beginning
0387     const_iterator cbegin() const ; ///<Returns an iterator to the beginning
0388 
0389     iterator       end()       ; ///<Returns an iterator to the end
0390     const_iterator end()  const; ///<Returns an iterator to the end
0391     const_iterator cend() const; ///<Returns an iterator to the end
0392 
0393     iterator        find( const string_type& key );            ///<Find a variable by its name
0394     const_iterator  find( const string_type& key ) const;   ///<Find a variable by its name
0395 
0396     std::size_t count(const string_type & st) const; ///<Number of variables
0397     void erase(const string_type & id); ///<Erase variable by id.
0398     ///Emplace an environment variable.
0399     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
0400 
0401     ///Default constructor
0402     basic_environment();
0403     ///Copy constructor.
0404     basic_environment(const basic_environment & );
0405     ///Move constructor.
0406     basic_environment(basic_environment && );
0407 
0408     ///Copy assignment.
0409     basic_environment& operator=(const basic_environment & );
0410     ///Move assignment.
0411     basic_environment& operator=(basic_environment && );
0412 
0413     typedef typename detail::implementation_type::native_handle_type native_handle;
0414 
0415     ///Check if environment has entries.
0416     bool empty();
0417     ///Get the number of variables.
0418     std::size_t size() const;
0419     ///Clear the environment. @attention Use with care, passed environment cannot be empty.
0420     void clear();
0421     ///Get the entry with the key. Throws if it does not exist.
0422     entry_type  at( const string_type& key );
0423     ///Get the entry with the key. Throws if it does not exist.
0424     const_entry_type at( const string_type& key ) const;
0425     ///Get the entry with the given key. It creates the entry if it doesn't exist.
0426     entry_type operator[](const string_type & key);
0427 
0428     /**Proxy class used for read access to members by [] or .at()
0429      * @attention Holds a reference to the environment it was created from.
0430      */
0431     template<typename Char, typename Environment>
0432     struct const_entry_type
0433     {
0434         typedef Char value_type;
0435         typedef const value_type * pointer;
0436         typedef std::basic_string<value_type> string_type;
0437         typedef boost::iterator_range<pointer> range;
0438         typedef Environment environment_t;
0439 
0440         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
0441         std::vector<string_type> to_vector() const
0442         ///Get the value as string.
0443         string_type to_string()              const
0444         ///Get the name of this entry.
0445         string_type get_name() const {return string_type(_name.begin(), _name.end());}
0446         ///Copy Constructor
0447         const_entry(const const_entry&) = default;
0448         ///Move Constructor
0449         const_entry& operator=(const const_entry&) = default;
0450         ///Check if the entry is empty.
0451         bool empty() const;
0452     };
0453 
0454     /**Proxy class used for read and write access to members by [] or .at()
0455      * @attention Holds a reference to the environment it was created from.
0456      */
0457     template<typename Char, typename Environment>
0458     struct entry_type
0459     {
0460 
0461         typedef Char value_type;
0462         typedef const value_type * pointer;
0463         typedef std::basic_string<value_type> string_type;
0464         typedef boost::iterator_range<pointer> range;
0465         typedef Environment environment_t;
0466 
0467         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
0468         std::vector<string_type> to_vector() const
0469         ///Get the value as string.
0470         string_type to_string()              const
0471         ///Get the name of this entry.
0472         string_type get_name() const {return string_type(_name.begin(), _name.end());}
0473         ///Copy Constructor
0474         entry(const entry&) = default;
0475         ///Move Constructor
0476         entry& operator=(const entry&) = default;
0477         ///Check if the entry is empty.
0478         bool empty() const;
0479 
0480         ///Assign a string to the value
0481         void assign(const string_type &value);
0482         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
0483         void assign(const std::vector<string_type> &value);
0484         ///Append a string to the end of the entry, it will separated by ';' or ':'.
0485         void append(const string_type &value);
0486         ///Reset the value
0487         void clear();
0488         ///Assign a string to the entry.
0489         entry &operator=(const string_type & value);
0490         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
0491         entry &operator=(const std::vector<string_type> & value);
0492         ///Append a string to the end of the entry, it will separated by ';' or ':'.
0493         entry &operator+=(const string_type & value);
0494     };
0495 
0496 };
0497 
0498 /**Template representation of the environment of this process. It takes a template
0499  * as template parameter to implement the environment. All instances of this class
0500  * refer to the same environment, but might not get updated if another one makes changes.
0501  */
0502 template<typename Char>
0503 class basic_native_environment
0504 {
0505 
0506 public:
0507     typedef std::basic_string<Char> string_type;
0508     typedef boost::transform_iterator<      entry_maker, Char**> iterator       ;
0509     typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
0510     typedef std::size_t                                             size_type      ;
0511 
0512     iterator       begin()        ; ///<Returns an iterator to the beginning
0513     const_iterator begin()  const ; ///<Returns an iterator to the beginning
0514     const_iterator cbegin() const ; ///<Returns an iterator to the beginning
0515 
0516     iterator       end()       ; ///<Returns an iterator to the end
0517     const_iterator end()  const; ///<Returns an iterator to the end
0518     const_iterator cend() const; ///<Returns an iterator to the end
0519 
0520     iterator        find( const string_type& key );            ///<Find a variable by its name
0521     const_iterator  find( const string_type& key ) const;   ///<Find a variable by its name
0522 
0523     std::size_t count(const string_type & st) const; ///<Number of variables
0524     void erase(const string_type & id); ///<Erase variable by id.
0525     ///Emplace an environment variable.
0526     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
0527 
0528     ///Default constructor
0529     basic_native_environment();
0530     ///Move constructor.
0531     basic_native_environment(basic_native_environment && );
0532     ///Move assignment.
0533     basic_native_environment& operator=(basic_native_environment && );
0534 
0535     typedef typename detail::implementation_type::native_handle_type native_handle;
0536 
0537     ///Check if environment has entries.
0538     bool empty();
0539     ///Get the number of variables.
0540     std::size_t size() const;
0541     ///Get the entry with the key. Throws if it does not exist.
0542     entry_type  at( const string_type& key );
0543     ///Get the entry with the key. Throws if it does not exist.
0544     const_entry_type at( const string_type& key ) const;
0545     ///Get the entry with the given key. It creates the entry if it doesn't exist.
0546     entry_type operator[](const string_type & key);
0547 
0548     /**Proxy class used for read access to members by [] or .at()
0549      * @attention Holds a reference to the environment it was created from.
0550      */
0551     template<typename Char, typename Environment>
0552     struct const_entry_type
0553     {
0554         typedef Char value_type;
0555         typedef const value_type * pointer;
0556         typedef std::basic_string<value_type> string_type;
0557         typedef boost::iterator_range<pointer> range;
0558         typedef Environment environment_t;
0559 
0560         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
0561         std::vector<string_type> to_vector() const
0562         ///Get the value as string.
0563         string_type to_string()              const
0564         ///Get the name of this entry.
0565         string_type get_name() const {return string_type(_name.begin(), _name.end());}
0566         ///Copy Constructor
0567         const_entry(const const_entry&) = default;
0568         ///Move Constructor
0569         const_entry& operator=(const const_entry&) = default;
0570         ///Check if the entry is empty.
0571         bool empty() const;
0572     };
0573 
0574     /**Proxy class used for read and write access to members by [] or .at()
0575      * @attention Holds a reference to the environment it was created from.
0576      */
0577     template<typename Char, typename Environment>
0578     struct entry_type
0579     {
0580 
0581         typedef Char value_type;
0582         typedef const value_type * pointer;
0583         typedef std::basic_string<value_type> string_type;
0584         typedef boost::iterator_range<pointer> range;
0585         typedef Environment environment_t;
0586 
0587         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
0588         std::vector<string_type> to_vector() const
0589         ///Get the value as string.
0590         string_type to_string()              const
0591         ///Get the name of this entry.
0592         string_type get_name() const {return string_type(_name.begin(), _name.end());}
0593         ///Copy Constructor
0594         entry(const entry&) = default;
0595         ///Move Constructor
0596         entry& operator=(const entry&) = default;
0597         ///Check if the entry is empty.
0598         bool empty() const;
0599 
0600         ///Assign a string to the value
0601         void assign(const string_type &value);
0602         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
0603         void assign(const std::vector<string_type> &value);
0604         ///Append a string to the end of the entry, it will separated by ';'  or ':'.
0605         void append(const string_type &value);
0606         ///Reset the value
0607         void clear();
0608         ///Assign a string to the entry.
0609         entry &operator=(const string_type & value);
0610         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
0611         entry &operator=(const std::vector<string_type> & value);
0612         ///Append a string to the end of the entry, it will separated by ';' or ':'.
0613         entry &operator+=(const string_type & value);
0614     };
0615 
0616 };
0617 
0618 #endif
0619 
0620 ///Definition of the environment for the current process.
0621 template<typename Char>
0622 class basic_native_environment : public basic_environment_impl<Char, detail::api::native_environment_impl>
0623 {
0624 public:
0625     using base_type = basic_environment_impl<Char, detail::api::native_environment_impl>;
0626     using base_type::base_type;
0627     using base_type::operator=;
0628 };
0629 
0630 ///Type definition to hold a seperate environment.
0631 template<typename Char>
0632 class basic_environment : public basic_environment_impl<Char, detail::api::basic_environment_impl>
0633 {
0634 public:
0635     using base_type = basic_environment_impl<Char, detail::api::basic_environment_impl>;
0636     using base_type::base_type;
0637     using base_type::operator=;
0638 };
0639 
0640 
0641 #if !defined(BOOST_NO_ANSI_APIS)
0642 ///Definition of the environment for the current process.
0643 typedef basic_native_environment<char>     native_environment;
0644 #endif
0645 ///Definition of the environment for the current process.
0646 typedef basic_native_environment<wchar_t> wnative_environment;
0647 
0648 #if !defined(BOOST_NO_ANSI_APIS)
0649 ///Type definition to hold a seperate environment.
0650 typedef basic_environment<char>     environment;
0651 #endif
0652 ///Type definition to hold a seperate environment.
0653 typedef basic_environment<wchar_t> wenvironment;
0654 
0655 }
0656 
0657 ///Namespace containing information of the calling process.
0658 namespace this_process
0659 {
0660 
0661 ///Definition of the native handle type.
0662 typedef ::boost::process::detail::api::native_handle_t native_handle_type;
0663 
0664 #if !defined(BOOST_NO_ANSI_APIS)
0665 ///Definition of the environment for this process.
0666 using ::boost::process::native_environment;
0667 #endif
0668 ///Definition of the environment for this process.
0669 using ::boost::process::wnative_environment;
0670 
0671 ///Get the process id of the current process.
0672 inline int get_id()                     { return ::boost::process::detail::api::get_id();}
0673 ///Get the native handle of the current process.
0674 inline native_handle_type native_handle()  { return ::boost::process::detail::api::native_handle();}
0675 #if !defined(BOOST_NO_ANSI_APIS)
0676 ///Get the enviroment of the current process.
0677 inline native_environment   environment() { return ::boost::process:: native_environment(); }
0678 #endif
0679 ///Get the enviroment of the current process.
0680 inline wnative_environment wenvironment() { return ::boost::process::wnative_environment(); }
0681 ///Get the path environment variable of the current process runs.
0682 inline std::vector<boost::process::filesystem::path> path()
0683 {
0684 #if defined(BOOST_WINDOWS_API)
0685     const ::boost::process::wnative_environment ne{};
0686     typedef typename ::boost::process::wnative_environment::const_entry_type value_type;
0687     static constexpr auto id = L"PATH";
0688 #else
0689     const ::boost::process::native_environment ne{};
0690     typedef typename ::boost::process::native_environment::const_entry_type value_type;
0691     static constexpr auto id = "PATH";
0692 #endif
0693 
0694     auto itr = std::find_if(ne.cbegin(), ne.cend(),
0695             [&](const value_type & e)
0696              {return id == ::boost::to_upper_copy(e.get_name(), ::boost::process::detail::process_locale());});
0697 
0698     if (itr == ne.cend())
0699         return {};
0700 
0701     auto vec = itr->to_vector();
0702 
0703     std::vector<boost::process::filesystem::path> val;
0704     val.resize(vec.size());
0705 
0706     std::copy(vec.begin(), vec.end(), val.begin());
0707 
0708     return val;
0709 }
0710 }
0711 }
0712 #endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENVIRONMENT_HPP_ */