123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896 |
- //
- // process/environment.hpp
- // ~~~~~~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2021 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_PROCESS_V2_ENVIRONMENT_HPP
- #define BOOST_PROCESS_V2_ENVIRONMENT_HPP
- #include <boost/process/v2/detail/config.hpp>
- #include <boost/process/v2/cstring_ref.hpp>
- #include <boost/process/v2/detail/utf8.hpp>
- #include <boost/type_traits.hpp>
- #include <functional>
- #include <memory>
- #include <numeric>
- #if !defined(GENERATING_DOCUMENTATION)
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- #include <boost/process/v2/detail/environment_win.hpp>
- #else
- #include <boost/process/v2/detail/environment_posix.hpp>
- #endif
- #endif
- BOOST_PROCESS_V2_BEGIN_NAMESPACE
- /// Namespace for information and functions regarding the calling process.
- namespace environment
- {
- #if defined(GENERATING_DOCUMENTATION)
- /// A char traits type that reflects the OS rules for string representing environment keys.
- /** Can be an alias of std::char_traits. May only be defined for `char` and `wchar_t`.
- *
- * Windows treats keys as case-insensitive yet perserving. The char traits are made to reflect
- * that behaviour.
- */
- tempalte<typename Char>
- using key_char_traits = implementation_defined ;
- /// A char traits type that reflects the OS rules for string representing environment values.
- /** Can be an alias of std::char_traits. May only be defined for `char` and `wchar_t`.
- */
- tempalte<typename Char>
- using value_char_traits = implementation_defined ;
- /// The character type used by the environment. Either `char` or `wchar_t`.
- using char_type = implementation_defined ;
- /// The equal character in an environment string used to separate key and value.
- constexpr char_type equality_sign = implementation_defined;
- /// The delimiter in environemtn lists. Commonly used by the `PATH` variable.
- constexpr char_type delimiter = implementation_defined;
- /// The native handle of an environment. Note that this can be an owning pointer and is generally not thread safe.
- using native_handle = implementation_defined;
- #endif
- /// The iterator used by a value or value_view to iterator through environments that are lists.
- struct value_iterator
- {
- using string_view_type = basic_string_view<char_type, value_char_traits<char_type>>;
- using difference_type = int;
- using reference = string_view_type;
- using iterator_category = std::forward_iterator_tag;
- value_iterator & operator++()
- {
- const auto delim = view_.find(delimiter);
- if (delim != string_view_type::npos)
- view_ = view_.substr(delim + 1);
- else
- view_ = view_.substr(view_.size());
- return *this;
- }
- value_iterator operator++(int)
- {
- auto last = *this;
- ++(*this);
- return last;
- }
- string_view_type operator*() const
- {
- const auto delim = view_.find(delimiter);
- if (delim == string_view_type::npos)
- return view_;
- else
- return view_.substr(0, delim);
- }
- value_iterator() = default;
- value_iterator(const value_iterator & ) = default;
- value_iterator(string_view_type view, std::size_t offset = 0u) : view_(view.substr(offset))
- {
- }
- friend bool operator==(const value_iterator & l, const value_iterator & r) { return l.view_ == r.view_; }
- friend bool operator!=(const value_iterator & l, const value_iterator & r) { return l.view_ != r.view_; }
- private:
- string_view_type view_;
- };
- /// A view type for a key of an environment
- struct key_view
- {
- using value_type = char_type;
- using traits_type = key_char_traits<char_type>;
- using string_view_type = basic_string_view<char_type, traits_type>;
- using string_type = std::basic_string<char_type, key_char_traits<char_type>>;
- key_view() noexcept = default;
- key_view( const key_view& p ) = default;
- key_view( key_view&& p ) noexcept = default;
- template<typename Source,
- typename = typename std::enable_if<is_constructible<string_view_type, Source>::value>::type>
- key_view( const Source& source ) : value_(source) {}
- key_view( const char_type * p) : value_(p) {}
- key_view( char_type * p) : value_(p) {}
- ~key_view() = default;
- key_view& operator=( const key_view& p ) = default;
- key_view& operator=( key_view&& p ) noexcept = default;
- key_view& operator=( string_view_type source )
- {
- value_ = source;
- return *this;
- }
- void swap( key_view& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- string_view_type native() const noexcept {return value_;}
- operator string_view_type() const {return native();}
- int compare( const key_view& p ) const noexcept {return value_.compare(p.value_);}
- int compare( string_view_type str ) const {return value_.compare(str);}
- int compare( const value_type* s ) const {return value_.compare(s);}
- template< class CharT, class Traits = std::char_traits<CharT>,
- class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc()) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(
- value_.data(), value_.size(), alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- string_type native_string() const
- {
- return basic_string<char_type, key_char_traits<char_type>>();
- }
- friend bool operator==(key_view l, key_view r) { return l.value_ == r.value_; }
- friend bool operator!=(key_view l, key_view r) { return l.value_ != r.value_; }
- friend bool operator<=(key_view l, key_view r) { return l.value_ <= r.value_; }
- friend bool operator>=(key_view l, key_view r) { return l.value_ >= r.value_; }
- friend bool operator< (key_view l, key_view r) { return l.value_ < r.value_; }
- friend bool operator> (key_view l, key_view r) { return l.value_ > r.value_; }
- bool empty() const {return value_.empty(); }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const key_view& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, key_view& p )
- {
- std::basic_string<CharT, Traits> t;
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(t);
- p = t;
- return is;
- }
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- private:
- string_view_type value_;
- };
- /// A view for a value in an environment
- struct value_view
- {
- using value_type = char_type;
- using string_view_type = basic_cstring_ref<char_type, value_char_traits<char_type>>;
- using string_type = std::basic_string<char_type, value_char_traits<char_type>>;
- using traits_type = value_char_traits<char_type>;
- value_view() noexcept = default;
- value_view( const value_view& p ) = default;
- value_view( value_view&& p ) noexcept = default;
- template<typename Source, typename = typename std::enable_if<is_constructible<string_view_type, Source>::value>::type>
- value_view( const Source& source ) : value_(source) {}
- value_view( const char_type * p) : value_(p) {}
- value_view( char_type * p) : value_(p) {}
- ~value_view() = default;
- value_view& operator=( const value_view& p ) = default;
- value_view& operator=( value_view&& p ) noexcept = default;
- value_view& operator=( string_view_type source )
- {
- value_ = source;
- return *this;
- }
- void swap( value_view& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- string_view_type native() const noexcept {return value_;}
- operator string_view_type() const {return native();}
- operator typename string_view_type::string_view_type() const {return value_; }
- int compare( const value_view& p ) const noexcept {return value_.compare(p.value_);}
- int compare( string_view_type str ) const {return value_.compare(str);}
- int compare( const value_type* s ) const {return value_.compare(s);}
- template< class CharT, class Traits = std::char_traits<CharT>,
- class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc() ) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(
- value_.data(), value_.size(), alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- string_type native_string() const
- {
- return basic_string<char_type, value_char_traits<char_type>>();
- }
- bool empty() const {return value_.empty(); }
- friend bool operator==(value_view l, value_view r) { return l.value_ == r.value_; }
- friend bool operator!=(value_view l, value_view r) { return l.value_ != r.value_; }
- friend bool operator<=(value_view l, value_view r) { return l.value_ <= r.value_; }
- friend bool operator>=(value_view l, value_view r) { return l.value_ >= r.value_; }
- friend bool operator< (value_view l, value_view r) { return l.value_ < r.value_; }
- friend bool operator> (value_view l, value_view r) { return l.value_ > r.value_; }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const value_view& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, value_view& p )
- {
- std::basic_string<CharT, Traits> t;
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(t);
- p = t;
- return is;
- }
- value_iterator begin() const {return value_iterator(value_.data());}
- value_iterator end() const {return value_iterator(value_.data() , value_.size());}
- const char_type * c_str() {return value_.c_str(); }
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- private:
- string_view_type value_;
- };
- /// A view for a key value pair in an environment
- struct key_value_pair_view
- {
- using value_type = char_type;
- using string_type = std::basic_string<char_type>;
- using string_view_type = basic_cstring_ref<char_type>;
- using traits_type = std::char_traits<char_type>;
- key_value_pair_view() noexcept = default;
- key_value_pair_view( const key_value_pair_view& p ) = default;
- key_value_pair_view( key_value_pair_view&& p ) noexcept = default;
- template<typename Source,
- typename = typename std::enable_if<is_constructible<string_view_type, Source>::value>::type>
- key_value_pair_view( const Source& source ) : value_(source) {}
- key_value_pair_view( const char_type * p) : value_(p) {}
- key_value_pair_view( char_type * p) : value_(p) {}
- ~key_value_pair_view() = default;
- key_value_pair_view& operator=( const key_value_pair_view& p ) = default;
- key_value_pair_view& operator=( key_value_pair_view&& p ) noexcept = default;
- void swap( key_value_pair_view& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- string_view_type native() const noexcept {return value_;}
- operator string_view_type() const {return native();}
- operator typename string_view_type::string_view_type() const {return value_; }
- int compare( key_value_pair_view p ) const noexcept
- {
- const auto c = key().compare(p.key());
- if (c != 0)
- return c;
- return value().compare(p.value());
- }
- int compare( const string_type& str ) const
- {
- return compare(key_value_pair_view(str));
- }
- int compare( string_view_type str ) const
- {
- string_type st(str.data(), str.size());
- return compare(st);
- }
- int compare( const value_type* s ) const
- {
- return compare(key_value_pair_view(s));
- }
- template< class CharT, class Traits = std::char_traits<CharT>, class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc()) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(value_.begin(), value_.size(), alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- string_type native_string() const
- {
- return basic_string<char_type>();
- }
- bool empty() const {return value_.empty(); }
- key_view key() const
- {
- auto eq = value_.find(equality_sign);
- if (eq == 0)
- {
- auto eq2 = value_.find(equality_sign, 1);
- if (eq2 != string_type::npos)
- eq = eq2;
- }
- const auto res = native().substr(0, eq == string_view_type::npos ? value_.size() : eq);
- return key_view::string_view_type(res.data(), res.size());
- }
- value_view value() const
- {
- auto eq = value_.find(equality_sign);
- if (eq == 0)
- {
- auto eq2 = value_.find(equality_sign, 1);
- if (eq2 != string_type::npos)
- eq = eq2;
- }
- return environment::value_view(native().substr(eq + 1));
- }
- friend bool operator==(key_value_pair_view l, key_value_pair_view r) { return l.compare(r) == 0; }
- friend bool operator!=(key_value_pair_view l, key_value_pair_view r) { return l.compare(r) != 0; }
- friend bool operator<=(key_value_pair_view l, key_value_pair_view r) { return l.compare(r) <= 0; }
- friend bool operator>=(key_value_pair_view l, key_value_pair_view r) { return l.compare(r) >= 0; }
- friend bool operator< (key_value_pair_view l, key_value_pair_view r) { return l.compare(r) < 0; }
- friend bool operator> (key_value_pair_view l, key_value_pair_view r) { return l.compare(r) > 0; }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const key_value_pair_view& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, key_value_pair_view& p )
- {
- std::basic_string<CharT, Traits> t;
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(t);
- p = t;
- return is;
- }
- template<std::size_t Idx>
- inline auto get() const -> typename conditional<Idx == 0u, BOOST_PROCESS_V2_NAMESPACE::environment::key_view,
- BOOST_PROCESS_V2_NAMESPACE::environment::value_view>::type;
- const value_type * c_str() const noexcept
- {
- return value_.data();
- }
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- private:
- string_view_type value_;
- };
- template<>
- inline key_view key_value_pair_view::get<0u>() const
- {
- return key();
- }
- template<>
- inline value_view key_value_pair_view::get<1u>() const
- {
- return value();
- }
- namespace detail
- {
- template<typename Char>
- std::size_t hash_step(std::size_t prev, Char c, std::char_traits<Char>)
- {
- return prev ^ (c << 1);
- }
- }
- inline std::size_t hash_value(const key_view & value)
- {
- std::size_t hash = 0u;
- for (auto c = value.data(); *c != *v2::detail::null_char_(*c); c++)
- hash = detail::hash_step(hash, *c, key_view::traits_type{});
- return hash ;
- }
- inline std::size_t hash_value(const BOOST_PROCESS_V2_NAMESPACE::environment::value_view & value)
- {
- std::size_t hash = 0u;
- for (auto c = value.data(); *c != *v2::detail::null_char_(*c); c++)
- hash = detail::hash_step(hash, *c, value_view::traits_type{});
- return hash ;
- }
- inline std::size_t hash_value(const BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view & value)
- {
- std::size_t hash = 0u;
- for (auto c = value.data(); *c != *v2::detail::null_char_(*c); c++)
- hash = detail::hash_step(hash, *c, key_value_pair_view::traits_type{});
- return hash ;
- }
- /// A class representing a key within an environment.
- struct key
- {
- using value_type = char_type;
- using traits_type = key_char_traits<char_type>;
- using string_type = std::basic_string<char_type, traits_type>;
- using string_view_type = basic_string_view<char_type, traits_type>;
- key() {}
- key( const key& p ) = default;
- key( key&& p ) noexcept = default;
- key( const string_type& source ) : value_(source) {}
- key( string_type&& source ) : value_(std::move(source)) {}
- key( const value_type * raw ) : value_(raw) {}
- key( value_type * raw ) : value_(raw) {}
- explicit key(key_view kv) : value_(kv.native_string()) {}
- template< class Source >
- key( const Source& source,
- decltype(std::declval<Source>().data()) = nullptr,
- decltype(std::declval<Source>().size()) = 0u)
- : value_(
- BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size()))
- {
- }
- key(const typename conditional<is_same<value_type, char>::value, wchar_t, char>::type * raw)
- : value_(BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- raw, std::char_traits<std::decay<std::remove_pointer<decltype(raw)>::type>::type>::length(raw)))
- {
- }
- template< class InputIt >
- key( InputIt first, InputIt last)
- : key(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last))
- {
- }
- ~key() = default;
- key& operator=( const key& p ) = default;
- key& operator=( key&& p )
- {
- value_ = std::move(p.value_);
- return *this;
- }
- key& operator=( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- key& operator=( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(source.data(), source.size());
- return *this;
- }
- key& assign( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- key& assign( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(source.data(), source.size());
- return *this;
- }
- template< class InputIt >
- key& assign( InputIt first, InputIt last )
- {
- return assign(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last));
- }
- void clear() {value_.clear();}
- void swap( key& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- const value_type* c_str() const noexcept {return value_.c_str();}
- const string_type& native() const noexcept {return value_;}
- string_view_type native_view() const noexcept {return value_;}
- operator string_type() const {return native();}
- operator string_view_type() const {return native_view();}
- int compare( const key& p ) const noexcept {return value_.compare(p.value_);}
- int compare( const string_type& str ) const {return value_.compare(str);}
- int compare( string_view_type str ) const {return -str.compare(value_);}
- int compare( const value_type* s ) const {return value_.compare(s);}
- template< class CharT, class Traits = std::char_traits<CharT>,
- class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc()) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(
- value_.data(), value_.size(), alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- const string_type & native_string() const
- {
- return value_;
- }
- bool empty() const {return value_.empty(); }
- friend bool operator==(const key & l, const key & r) { return l.value_ == r.value_; }
- friend bool operator!=(const key & l, const key & r) { return l.value_ != r.value_; }
- friend bool operator<=(const key & l, const key & r) { return l.value_ <= r.value_; }
- friend bool operator>=(const key & l, const key & r) { return l.value_ >= r.value_; }
- friend bool operator< (const key & l, const key & r) { return l.value_ < r.value_; }
- friend bool operator> (const key & l, const key & r) { return l.value_ > r.value_; }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const key& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, key& p )
- {
- std::basic_string<CharT, Traits> t;
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(t);
- p = t;
- return is;
- }
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- private:
- string_type value_;
- };
- #if !defined(GENERATING_DOCUMENTATION)
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator==(const T &l, const U & r) { return key_view(l) == key_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator!=(const T &l, const U & r) { return key_view(l) != key_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator<=(const T &l, const U & r) { return key_view(l) <= key_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator <(const T &l, const U & r) { return key_view(l) < key_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator>=(const T &l, const U & r) { return key_view(l) >= key_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key>::value || std::is_same<T, key_view>::value) &&
- std::is_convertible<const U &, key_view>::value)
- ||
- ((std::is_same<U, key>::value || std::is_same<U, key_view>::value) &&
- std::is_convertible<const T & , key_view>::value),
- bool>::type
- operator >(const T &l, const U & r) { return key_view(l) > key_view(r); }
- #else
- bool operator==(const value_view &, const value_view);
- bool operator!=(const value_view &, const value_view);
- bool operator<=(const value_view &, const value_view);
- bool operator< (const value_view &, const value_view);
- bool operator> (const value_view &, const value_view);
- bool operator>=(const value_view &, const value_view);
- #endif
- struct value
- {
- using value_type = char_type;
- using traits_type = value_char_traits<char_type>;
- using string_type = std::basic_string<char_type, traits_type>;
- using string_view_type = basic_cstring_ref<char_type, traits_type>;
- value() {}
- value( const value& p ) = default;
- value( const string_type& source ) : value_(source) {}
- value( string_type&& source ) : value_(std::move(source)) {}
- value( const value_type * raw ) : value_(raw) {}
- value( value_type * raw ) : value_(raw) {}
- explicit value(value_view kv) : value_(kv.c_str()) {}
- template< class Source >
- value( const Source& source,
- decltype(std::declval<Source>().data()) = nullptr,
- decltype(std::declval<Source>().size()) = 0u)
- : value_(BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size()))
- {
- }
- value(const typename conditional<is_same<value_type, char>::value, wchar_t, char>::type * raw)
- : value_(BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- raw, std::char_traits<std::decay<std::remove_pointer<decltype(raw)>::type>::type>::length(raw)))
- {
- }
- template< class InputIt >
- value( InputIt first, InputIt last)
- : value(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last))
- {
- }
- ~value() = default;
- value& operator=( const value& p ) = default;
- value& operator=( value&& p )
- {
- value_ = std::move(p.value_);
- return *this;
- }
- value& operator=( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- value& operator=( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size);
- return *this;
- }
- value& assign( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- value& assign( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size());
- return *this;
- }
- template< class InputIt >
- value& assign( InputIt first, InputIt last )
- {
- return assign(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last));
- }
- void push_back(const value & sv)
- {
- (value_ += delimiter) += sv;
- }
- void clear() {value_.clear();}
- void swap( value& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- const value_type* c_str() const noexcept {return value_.c_str();}
- const string_type& native() const noexcept {return value_;}
- string_view_type native_view() const noexcept {return value_;}
- operator string_type() const {return native();}
- operator string_view_type() const {return native_view();}
- operator typename string_view_type::string_view_type() const {return value_; }
- int compare( const value& p ) const noexcept {return value_.compare(p.value_);}
- int compare( const string_type& str ) const {return value_.compare(str);}
- int compare( string_view_type str ) const {return -str.compare(value_);}
- int compare( const value_type* s ) const {return value_.compare(s);}
- template< class CharT, class Traits = std::char_traits<CharT>,
- class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc()) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(
- value_.data(), value_.size(),alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- const string_type & native_string() const
- {
- return value_;
- }
- bool empty() const {return value_.empty(); }
- friend bool operator==(const value & l, const value & r) { return l.value_ == r.value_; }
- friend bool operator!=(const value & l, const value & r) { return l.value_ != r.value_; }
- friend bool operator<=(const value & l, const value & r) { return l.value_ <= r.value_; }
- friend bool operator>=(const value & l, const value & r) { return l.value_ >= r.value_; }
- friend bool operator< (const value & l, const value & r) { return l.value_ < r.value_; }
- friend bool operator> (const value & l, const value & r) { return l.value_ > r.value_; }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const value& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, value& p )
- {
- std::basic_string<CharT, Traits> t;
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(t);
- p = t;
- return is;
- }
- value_iterator begin() const {return value_iterator(value_.data());}
- value_iterator end() const {return value_iterator(value_.data(), value_.size());}
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- private:
- string_type value_;
- };
- #if !defined(GENERATING_DOCUMENTATION)
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator==(const T &l, const U & r) { return value_view(l) == value_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator!=(const T &l, const U & r) { return value_view(l) != value_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator<=(const T &l, const U & r) { return value_view(l) <= value_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator <(const T &l, const U & r) { return value_view(l) < value_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator>=(const T &l, const U & r) { return value_view(l) >= value_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, value>::value || std::is_same<T, value_view>::value) &&
- std::is_convertible<const U &, value_view>::value)
- ||
- ((std::is_same<U, value>::value || std::is_same<U, value_view>::value) &&
- std::is_convertible<const T & , value_view>::value),
- bool>::type
- operator >(const T &l, const U & r) { return value_view(l) > value_view(r); }
- #else
- bool operator==(const value_view &, const value_view);
- bool operator!=(const value_view &, const value_view);
- bool operator<=(const value_view &, const value_view);
- bool operator< (const value_view &, const value_view);
- bool operator> (const value_view &, const value_view);
- bool operator>=(const value_view &, const value_view);
- #endif
- struct key_value_pair
- {
- using value_type = char_type;
- using traits_type = std::char_traits<char_type>;
- using string_type = std::basic_string<char_type>;
- using string_view_type = basic_cstring_ref<char_type>;
- key_value_pair() {}
- key_value_pair( const key_value_pair& p ) = default;
- key_value_pair( key_value_pair&& p ) noexcept = default;
- key_value_pair(key_view key, value_view value) : value_(key.basic_string<char_type, traits_type>() + equality_sign +
- value.basic_string<char_type, traits_type>()) {}
- key_value_pair(key_view key, std::initializer_list<basic_string_view<char_type>> values)
- {
- const auto sz = std::accumulate(values.begin(), values.end(),
- key.size(), [](std::size_t sz, const basic_string_view<char_type> & str) { return sz + str.size() + 1;});
- value_.reserve(sz);
- value_.append(key.data(), key.size());
- value_ += equality_sign;
- for (auto & value : values)
- {
- if (value_.back() != equality_sign)
- value_ += delimiter;
- value_.append(value.data(), value.size());
- }
- }
- key_value_pair( const string_type& source ) : value_(source) {}
- key_value_pair( string_type&& source ) : value_(std::move(source)) {}
- key_value_pair( const value_type * raw ) : value_(raw) {}
- key_value_pair( value_type * raw ) : value_(raw) {}
- explicit key_value_pair(key_value_pair_view kv) : value_(kv.c_str()) {}
- template< class Source >
- key_value_pair( const Source& source,
- decltype(std::declval<Source>().data()) = nullptr,
- decltype(std::declval<Source>().size()) = 0u)
- : value_(BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size()))
- {
- }
- template< typename Key,
- typename Value >
- key_value_pair(
- const std::pair<Key, Value> & kv/*,
- typename std::enable_if<std::is_constructible<struct key, Key >::value &&
- std::is_constructible<struct value, Value>::value
- >::type = 0*/) : value_(((struct key)(kv.first)).basic_string<char_type, traits_type>() + equality_sign
- + ((struct value)(kv.second)).basic_string<char_type, traits_type>())
- {}
- key_value_pair(const typename conditional<is_same<value_type, char>::value, wchar_t, char>::type * raw)
- : value_(BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- raw,
- std::char_traits<std::decay<std::remove_pointer<decltype(raw)>::type>::type>::length(raw)))
- {
- }
- template< class InputIt , typename std::iterator_traits<InputIt>::iterator_category>
- key_value_pair( InputIt first, InputIt last )
- : key_value_pair(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last))
- {
- }
- ~key_value_pair() = default;
- key_value_pair& operator=( const key_value_pair& p ) = default;
- key_value_pair& operator=( key_value_pair&& p )
- {
- value_ = std::move(p.value_);
- return *this;
- }
- key_value_pair& operator=( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- key_value_pair& operator=( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size());
- return *this;
- }
- key_value_pair& assign( string_type&& source )
- {
- value_ = std::move(source);
- return *this;
- }
- template< class Source >
- key_value_pair& assign( const Source& source )
- {
- value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
- source.data(), source.size());
- return *this;
- }
- template< class InputIt >
- key_value_pair& assign( InputIt first, InputIt last )
- {
- return assign(std::basic_string<typename std::iterator_traits<typename std::decay<InputIt>::type>::value_type>(first, last));
- }
- void clear() {value_.clear();}
- void swap( key_value_pair& other ) noexcept
- {
- std::swap(value_, other.value_);
- }
- const value_type* c_str() const noexcept {return value_.c_str();}
- const string_type& native() const noexcept {return value_;}
- string_view_type native_view() const noexcept {return value_;}
- operator string_type() const {return native();}
- operator string_view_type() const {return native_view();}
- operator typename string_view_type::string_view_type() const {return native_view();}
- operator key_value_pair_view() const {return native_view();}
- int compare( const key_value_pair& p ) const noexcept
- {
- return key_value_pair_view(*this).compare(key_value_pair_view(p));
- }
-
- int compare( const string_type& str ) const
- {
- return key_value_pair_view(*this).compare(str);
- }
- int compare( string_view_type str ) const
- {
- return key_value_pair_view(*this).compare(str);
- }
- int compare( const value_type* s ) const
- {
- return key_value_pair_view(*this).compare(s);
- }
- template< class CharT, class Traits = std::char_traits<CharT>, class Alloc = std::allocator<CharT> >
- std::basic_string<CharT,Traits,Alloc>
- basic_string( const Alloc& alloc = Alloc() ) const
- {
- return BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<CharT, Traits>(value_.data(), value_.size(), alloc);
- }
- std::string string() const {return basic_string<char>();}
- std::wstring wstring() const {return basic_string<wchar_t>();}
- const string_type & native_string() const
- {
- return value_;
- }
- friend bool operator==(const key_value_pair & l, const key_value_pair & r) { return l.compare(r) == 0; }
- friend bool operator!=(const key_value_pair & l, const key_value_pair & r) { return l.compare(r) != 0; }
- friend bool operator<=(const key_value_pair & l, const key_value_pair & r) { return l.compare(r) <= 0; }
- friend bool operator>=(const key_value_pair & l, const key_value_pair & r) { return l.compare(r) >= 0; }
- friend bool operator< (const key_value_pair & l, const key_value_pair & r) { return l.compare(r) < 0; }
- friend bool operator> (const key_value_pair & l, const key_value_pair & r) { return l.compare(r) > 0; }
- bool empty() const {return value_.empty(); }
- struct key_view key() const
- {
- auto eq = value_.find(equality_sign);
- if (eq == 0)
- {
- auto eq2 = value_.find(equality_sign, 1);
- if (eq2 != string_type::npos)
- eq = eq2;
- }
- const auto k = native_view().substr(0, eq);
- return BOOST_PROCESS_V2_NAMESPACE::environment::key_view::string_view_type (k.data(), k.size());
- }
- struct value_view value() const
- {
- auto eq = value_.find(equality_sign);
- if (eq == 0)
- {
- auto eq2 = value_.find(equality_sign, 1);
- if (eq2 != string_type::npos)
- eq = eq2;
- }
- return value_view::string_view_type(native_view().substr(eq + 1));
- }
- template< class CharT, class Traits >
- friend std::basic_ostream<CharT,Traits>&
- operator<<( std::basic_ostream<CharT,Traits>& os, const key_value_pair& p )
- {
- os << BOOST_PROCESS_V2_NAMESPACE::quoted(p.basic_string<CharT,Traits>());
- return os;
- }
- template< class CharT, class Traits >
- friend std::basic_istream<CharT,Traits>&
- operator>>( std::basic_istream<CharT,Traits>& is, key_value_pair& p )
- {
- is >> BOOST_PROCESS_V2_NAMESPACE::quoted(p.value_);
- return is;
- }
- const value_type * data() const {return value_.data(); }
- std::size_t size() const {return value_.size(); }
- template<std::size_t Idx>
- inline auto get() const
- -> typename conditional<Idx == 0u, BOOST_PROCESS_V2_NAMESPACE::environment::key_view,
- BOOST_PROCESS_V2_NAMESPACE::environment::value_view>::type;
- private:
- string_type value_;
- };
- #if !defined(GENERATING_DOCUMENTATION)
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator==(const T &l, const U & r) { return key_value_pair_view(l) == key_value_pair_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator!=(const T &l, const U & r) { return key_value_pair_view(l) != key_value_pair_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator<=(const T &l, const U & r) { return key_value_pair_view(l) <= key_value_pair_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator <(const T &l, const U & r) { return key_value_pair_view(l) < key_value_pair_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator>=(const T &l, const U & r) { return key_value_pair_view(l) >= key_value_pair_view(r); }
- template<typename T, typename U>
- typename std::enable_if<
- ((std::is_same<T, key_value_pair>::value || std::is_same<T, key_value_pair_view>::value) &&
- std::is_convertible<const U &, key_value_pair_view>::value)
- ||
- ((std::is_same<U, key_value_pair>::value || std::is_same<U, key_value_pair_view>::value) &&
- std::is_convertible<const T & , key_value_pair_view>::value),
- bool>::type
- operator >(const T &l, const U & r) { return key_value_pair_view(l) > key_value_pair_view(r); }
- #else
- bool operator==(const key_value_pair_view &, const key_value_pair_view);
- bool operator!=(const key_value_pair_view &, const key_value_pair_view);
- bool operator<=(const key_value_pair_view &, const key_value_pair_view);
- bool operator< (const key_value_pair_view &, const key_value_pair_view);
- bool operator> (const key_value_pair_view &, const key_value_pair_view);
- bool operator>=(const key_value_pair_view &, const key_value_pair_view);
- #endif
- template<>
- inline key_view key_value_pair::get<0u>() const
- {
- return key();
- }
- template<>
- inline value_view key_value_pair::get<1u>() const
- {
- return value();
- }
- }
- BOOST_PROCESS_V2_END_NAMESPACE
- namespace std
- {
- template<>
- class tuple_size<BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair> : integral_constant<std::size_t, 2u> {};
- template<>
- class tuple_element<0u, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair>
- {
- public:
- using type = BOOST_PROCESS_V2_NAMESPACE::environment::key_view;
- };
- template<>
- class tuple_element<1u, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair>
- {
- public:
- using type = BOOST_PROCESS_V2_NAMESPACE::environment::value_view;
- };
- template<std::size_t Idx>
- inline auto get(const BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair & kvp)
- -> typename std::tuple_element<Idx, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair>::type
- {
- return kvp.get<Idx>();
- }
- template<>
- class tuple_size<BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view> : integral_constant<std::size_t, 2u> {};
- template<>
- class tuple_element<0u, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view>
- {
- public:
- using type = BOOST_PROCESS_V2_NAMESPACE::environment::key_view;
- };
- template<>
- class tuple_element<1u, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view>
- {
- public:
- using type = BOOST_PROCESS_V2_NAMESPACE::environment::value_view;
- };
- template<std::size_t Idx>
- inline auto get(BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view kvp)
- -> typename std::tuple_element<Idx, BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view>::type
- {
- return kvp.get<Idx>();
- }
- }
- BOOST_PROCESS_V2_BEGIN_NAMESPACE
- namespace environment
- {
- /// A view object for the current environment of this process.
- /**
- * The view might (windows) or might not (posix) be owning;
- * if it owns it will deallocate the on destruction, like a unique_ptr.
- *
- * Note that accessing the environment in this way is not thread-safe.
- *
- * @code
- *
- * void dump_my_env(current_view env = current())
- * {
- * for (auto & [k, v] : env)
- * std::cout << k.string() << " = " << v.string() << std::endl;
- * }
- *
- * @endcode
- *
- *
- */
- struct current_view
- {
- using native_handle_type = environment::native_handle_type;
- using value_type = key_value_pair_view;
- current_view() = default;
- current_view(current_view && nt) = default;
- native_handle_type native_handle() { return handle_.get(); }
- struct iterator
- {
- using value_type = key_value_pair_view;
- using difference_type = int;
- using reference = key_value_pair_view;
- using pointer = key_value_pair_view;
- using iterator_category = std::forward_iterator_tag;
- iterator() = default;
- iterator(const iterator & ) = default;
- iterator(const native_iterator &native_handle) : iterator_(native_handle) {}
- iterator & operator++()
- {
- iterator_ = detail::next(iterator_);
- return *this;
- }
- iterator operator++(int)
- {
- auto last = *this;
- iterator_ = detail::next(iterator_);
- return last;
- }
- key_value_pair_view operator*() const
- {
- return detail::dereference(iterator_);
- }
- friend bool operator==(const iterator & l, const iterator & r) {return l.iterator_ == r.iterator_;}
- friend bool operator!=(const iterator & l, const iterator & r) {return l.iterator_ != r.iterator_;}
- private:
- environment::native_iterator iterator_;
- };
- iterator begin() const {return iterator(handle_.get());}
- iterator end() const {return iterator(detail::find_end(handle_.get()));}
- private:
- std::unique_ptr<typename remove_pointer<native_handle_type>::type,
- detail::native_handle_deleter> handle_{environment::detail::load_native_handle()};
- };
- /// Obtain a handle to the current environment
- inline current_view current() {return current_view();}
- namespace detail
- {
- template<typename Environment>
- auto find_key(Environment & env, key_view ky)
- -> typename std::enable_if<std::is_convertible<decltype(*std::begin(env)), key_value_pair_view>::value, value_view>::type
- {
- const auto itr = std::find_if(std::begin(env), std::end(env),
- [&](key_value_pair_view vp)
- {
- auto tmp = std::get<0>(vp) == ky;
- if (tmp)
- return true;
- else
- return false;
- });
-
- if (itr != std::end(env))
- return key_value_pair_view(*itr).value();
- else
- return {};
- }
- template<typename Environment>
- auto find_key(Environment & env, key_view ky)
- -> typename std::enable_if<
- !std::is_convertible<decltype(*std::begin(env)), key_value_pair_view>::value &&
- std::is_convertible<decltype(*std::begin(env)), key_value_pair>::value,
- value>::type
- {
- const auto itr = std::find_if(std::begin(env), std::end(env),
- [&](key_value_pair vp)
- {
- auto tmp = std::get<0>(vp) == ky;
- if (tmp)
- return true;
- else
- return false;
- });
- if (itr != std::end(env))
- return key_value_pair(*itr).value();
- else
- return {};
- }
- }
- /// Find the home folder in an environment-like type.
- /**
- * @param env The environment to search. Defaults to the current environment of this process
- *
- * The environment type passed in must be a range with value T that fulfills the following requirements:
- *
- * For `T value`
- *
- * - std::get<0>(value) must return a type comparable to `key_view`.
- * - std::get<1>(value) must return a type convertible to filesystem::path.
- *
- * @return A filesystem::path to the home directory or an empty path if it cannot be found.
- *
- */
- template<typename Environment = current_view>
- inline filesystem::path home(Environment && env = current())
- {
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- return detail::find_key(env, L"HOMEDRIVE").native_string()
- + detail::find_key(env, L"HOMEPATH").native_string();
- #else
- return detail::find_key(env, "HOME").native_string();
- #endif
- }
- /// Find the executable `name` in an environment-like type.
- /**
- * @param env The environment to search. Defaults to the current environment of this process
- *
- * The environment type passed in must be a range with value T that fulfills the following requirements:
- *
- * For `T value`
- *
- * - std::get<0>(value) must return a type comparable to `key_view`.
- * - std::get<1>(value) must return a type convertible to `value_view`.
- *
- *
- * @return A filesystem::path to the executable or an empty path if it cannot be found.
- *
- */
- template<typename Environment = current_view>
- inline BOOST_PROCESS_V2_NAMESPACE::filesystem::path find_executable(
- BOOST_PROCESS_V2_NAMESPACE::filesystem::path name,
- Environment && env = current())
- {
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- auto path = detail::find_key(env, L"PATH");
- auto pathext = detail::find_key(env, L"PATHEXT");
- for (auto pp_view : path)
- {
- // first check if it has the extension already
- BOOST_PROCESS_V2_NAMESPACE::filesystem::path full_nm(name);
- BOOST_PROCESS_V2_NAMESPACE::filesystem::path pp(pp_view.begin(), pp_view.end());
- auto p = pp / full_nm;
- error_code ec;
- if (detail::is_executable(p, ec) && !ec)
- return p;
- for (auto ext : pathext)
- {
- ec.clear();
- BOOST_PROCESS_V2_NAMESPACE::filesystem::path nm(name);
- nm.concat(ext.begin(), ext.end());
- auto p = pp / nm;
- if (detail::is_executable(p, ec) && !ec)
- return p;
- }
- }
- #else
- for (auto pp_view : detail::find_key(env, "PATH"))
- {
- auto p = BOOST_PROCESS_V2_NAMESPACE::filesystem::path(pp_view.begin(), pp_view.end()) / name;
- error_code ec;
- bool is_exec = detail::is_executable(p, ec);
- if (!ec && is_exec)
- return p;
- }
- #endif
- return {};
- }
- /// Get an environment variable from the current process.
- inline value get(const key & k, error_code & ec) { return detail::get(k.c_str(), ec);}
- /// Throwing @overload value get(const key & k, error_code & ec)
- inline value get(const key & k)
- {
- error_code ec;
- auto tmp = detail::get(k.c_str(), ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::get");
- return tmp;
- }
- /// Disambiguating @overload value get(const key & k, error_code & ec)
- inline value get(basic_cstring_ref<char_type, key_char_traits<char_type>> k, error_code & ec)
- {
- return detail::get(k, ec);
- }
- /// Disambiguating @overload value get(const key & k)
- inline value get(basic_cstring_ref<char_type, key_char_traits<char_type>> k)
- {
- error_code ec;
- auto tmp = detail::get(k, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::get");
- return tmp;
- }
- /// Disambiguating @overload value get(const key & k, error_code & ec)
- inline value get(const char_type * c, error_code & ec) { return detail::get(c, ec);}
- /// Disambiguating @overload value get(const key & k)
- inline value get(const char_type * c)
- {
- error_code ec;
- auto tmp = detail::get(c, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::get");
- return tmp;
- }
- /// Set an environment variable for the current process.
- inline void set(const key & k, value_view vw, error_code & ec) { detail::set(k, vw, ec);}
- /// Throwing @overload void set(const key & k, value_view vw, error_code & ec)
- inline void set(const key & k, value_view vw)
- {
- error_code ec;
- detail::set(k, vw, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- inline void set(basic_cstring_ref<char_type, key_char_traits<char_type>> k, value_view vw, error_code & ec) { detail::set(k, vw, ec);}
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- inline void set(basic_cstring_ref<char_type, key_char_traits<char_type>> k, value_view vw)
- {
- error_code ec;
- detail::set(k, vw, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- inline void set(const char_type * k, value_view vw, error_code & ec) { detail::set(k, vw, ec);}
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- inline void set(const char_type * k, value_view vw)
- {
- error_code ec;
- detail::set(k, vw, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(const key & k, const Char * vw, error_code & ec)
- {
- value val{vw};
- detail::set(k, val, ec);
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(const key & k, const Char * vw)
- {
- error_code ec;
- value val{vw};
- detail::set(k, val, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(basic_cstring_ref<char_type, key_char_traits<char_type>> k, const Char * vw, error_code & ec)
- {
- value val{vw};
- detail::set(k, val, ec);
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(basic_cstring_ref<char_type, key_char_traits<char_type>> k, const Char * vw)
- {
- error_code ec;
- value val{vw};
- detail::set(k, val, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(const char_type * k, const Char * vw, error_code & ec)
- {
- value val{vw};
- detail::set(k, val, ec);
- }
- /// Disambiguating @overload void set(const key & k, value_view vw, error_code & ec)
- template<typename Char, typename = typename std::enable_if<!std::is_same<Char, char_type>::value>::type>
- inline void set(const char_type * k, const Char * vw)
- {
- error_code ec;
- value val{vw};
- detail::set(k, val, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::set");
- }
- /// Remove an environment variable from the current process.
- inline void unset(const key & k, error_code & ec) { detail::unset(k, ec);}
- /// Throwing @overload void unset(const key & k, error_code & ec)
- inline void unset(const key & k)
- {
- error_code ec;
- detail::unset(k, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::unset");
- }
- /// Disambiguating @overload void unset(const key & k, error_code & ec)
- inline void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> k, error_code & ec)
- {
- detail::unset(k, ec);
- }
- /// Disambiguating @overload void unset(const key & k, error_code & ec)
- inline void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> k)
- {
- error_code ec;
- detail::unset(k, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::unset");
- }
- /// Disambiguating @overload void unset(const key & k, error_code & ec)
- inline void unset(const char_type * c, error_code & ec) { detail::unset(c, ec);}
- /// Disambiguating @overload void unset(const key & k, error_code & ec)
- inline void unset(const char_type * c)
- {
- error_code ec;
- detail::unset(c, ec);
- BOOST_PROCESS_V2_NAMESPACE::detail::throw_error(ec, "environment::unset");
- }
- }
- // sub process environment stuff
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- namespace windows { struct default_launcher ;}
- #else
- namespace posix { struct default_launcher ;}
- #endif
- /// Initializer for the environment of sub process.
- /**
- * This will set the environment in a subprocess:
- *
- * @code {.cpp}
- *
- * process proc{executor, find_executable("printenv"), {"foo"}, process_environment{"foo=bar"}};
- * @endcode
- *
- * The environment initializer will persist it's state, so that it can
- * be used multiple times. Do however note the the Operating System is
- * allowed to modify the internal state.
- *
- * @code {.cpp}
- * auto exe = find_executable("printenv");
- * process_environment env = {"FOO=BAR", "BAR=FOO"};
- *
- * process proc1(executor, exe, {"FOO"}, env);
- * process proc2(executor, exe, {"BAR"}, env);
- * @endcode
- *
- *
- */
- struct process_environment
- {
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- template<typename Args>
- static
- std::vector<wchar_t> build_env(Args && args,
- typename std::enable_if<
- std::is_convertible<
- decltype(*std::begin(std::declval<Args>())),
- wcstring_ref>::value>::type * = nullptr)
- {
- std::vector<wchar_t> res;
- std::size_t sz = 1;
- for (wcstring_ref cs : std::forward<Args>(args))
- sz =+ cs.size() + 1;
- res.reserve(sz);
-
- for (wcstring_ref cs : std::forward<Args>(args))
- res.insert(res.end(), cs.begin(), std::next(cs.end()));
-
- res.push_back(L'\0');
- return res;
- }
- template<typename Args>
- std::vector<wchar_t> build_env(Args && args,
- typename std::enable_if<
- !std::is_convertible<
- decltype(*std::begin(std::declval<Args>())),
- wcstring_ref>::value>::type * = nullptr)
- {
- for (auto && arg: std::forward<Args>(args))
- env_buffer.emplace_back(arg);
- return build_env(env_buffer);
- }
- process_environment(std::initializer_list<string_view> sv) : unicode_env{build_env(sv)} {}
- process_environment(std::initializer_list<wstring_view> sv) : unicode_env{build_env(sv)} {}
- template<typename Args>
- process_environment(Args && args) : unicode_env{build_env(std::forward<Args>(args))}
- {
- }
- error_code error() {return ec;}
- error_code ec;
- std::vector<environment::key_value_pair> env_buffer;
- std::vector<wchar_t> unicode_env;
- BOOST_PROCESS_V2_DECL
- error_code on_setup(windows::default_launcher & launcher,
- const filesystem::path &, const std::wstring &);
- #else
- template<typename Args>
- static
- std::vector<const char *> build_env(Args && args,
- typename std::enable_if<
- std::is_convertible<
- decltype(*std::begin(std::declval<Args>())),
- cstring_ref>::value>::type * = nullptr)
- {
- std::vector<const char *> env;
- for (auto && e : args)
- env.push_back(e.c_str());
- env.push_back(nullptr);
- return env;
- }
- template<typename Args>
- std::vector<const char *> build_env(Args && args,
- typename std::enable_if<
- !std::is_convertible<
- decltype(*std::begin(std::declval<Args>())),
- cstring_ref>::value>::type * = nullptr)
- {
- std::vector<const char *> env;
- for (auto && arg: std::forward<Args>(args))
- env_buffer.emplace_back(arg);
- for (auto && e : env_buffer)
- env.push_back(e.c_str());
- env.push_back(nullptr);
- return env;
- }
- process_environment(std::initializer_list<string_view> sv) : env{build_env(sv)} { }
- template<typename Args>
- process_environment(Args && args) : env(build_env(std::forward<Args>(args)))
- {
- }
- BOOST_PROCESS_V2_DECL
- error_code on_setup(posix::default_launcher & launcher,
- const filesystem::path &, const char * const *);
- std::vector<environment::key_value_pair> env_buffer;
- std::vector<const char *> env;
- #endif
- };
- BOOST_PROCESS_V2_END_NAMESPACE
- namespace std
- {
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::key_view>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::key_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::value_view>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::value_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::key>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::key_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::value>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::value_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- template<>
- struct hash<BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair>
- {
- std::size_t operator()( BOOST_PROCESS_V2_NAMESPACE::environment::key_value_pair_view kv) const noexcept
- {
- return BOOST_PROCESS_V2_NAMESPACE::environment::hash_value(kv);
- }
- };
- }
- #if defined(BOOST_PROCESS_V2_HEADER_ONLY)
- #include <boost/process/v2/impl/environment.ipp>
- #include <boost/process/v2/detail/impl/environment.ipp>
- #endif
- #endif //BOOST_PROCESS_V2_ENVIRONMENT_HPP
|