hunk.code_window: ## Using Release Channels for Environment Variable Configuration
   Enironment variables don't exist explicitly, but you can utilize release channels to make that happen!
   Say you have a workflow of releasing builds like this:
   - `exp publish --release-channel prod-v1`
   - `exp publish --release-channel prod-v2`
  
hunk.labels: keep keep replace keep keep keep keep keep
hunk.after_edit: Environment variables don't exist explicitly, but you can utilize release channels to make that happen!
  
hunk.file_path: docs/versions/unversioned/guides/release-channels.md
hunk.type: replace
file: /*=============================================================================
      Copyright (c) 2001-2003 Joel de Guzman
      Copyright (c) 2001-2003 Daniel Nuffer
      http://spirit.sourceforge.net/
  
      Use, modification and distribution is subject to 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_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
  #define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
  
  ///////////////////////////////////////////////////////////////////////////////
  #include <bitset>
  #include <boost/xpressive/detail/utility/chset/basic_chset.hpp>
  
  ///////////////////////////////////////////////////////////////////////////////
  namespace boost { namespace xpressive { namespace detail
  {
  
  ///////////////////////////////////////////////////////////////////////////////
  //
  //  basic_chset: character set implementation
  //
  ///////////////////////////////////////////////////////////////////////////////
  template<typename Char>
  inline basic_chset<Char>::basic_chset()
  {
  }
  
  //////////////////////////////////
  template<typename Char>
  inline basic_chset<Char>::basic_chset(basic_chset const &arg)
    : rr_(arg.rr_)
  {
  }
  
  //////////////////////////////////
  template<typename Char>
  inline bool basic_chset<Char>::empty() const
  {
      return this->rr_.empty();
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline bool basic_chset<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
  {
      return this->rr_.test(v);
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline bool basic_chset<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
  {
      return this->rr_.test(v, tr);
  }
  
  //////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::set(Char from, Char to)
  {
      this->rr_.set(range<Char>(from, to));
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset<Char>::set(Char from, Char to, Traits const &)
  {
      this->rr_.set(range<Char>(from, to));
  }
  
  //////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::set(Char c)
  {
      this->rr_.set(range<Char>(c, c));
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset<Char>::set(Char c, Traits const &)
  {
      this->rr_.set(range<Char>(c, c));
  }
  
  //////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::clear(Char c)
  {
      this->rr_.clear(range<Char>(c, c));
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset<Char>::clear(Char c, Traits const &)
  {
      this->rr_.clear(range<Char>(c, c));
  }
  
  //////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::clear(Char from, Char to)
  {
      this->rr_.clear(range<Char>(from, to));
  }
  
  //////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset<Char>::clear(Char from, Char to, Traits const &)
  {
      this->rr_.clear(range<Char>(from, to));
  }
  
  //////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::clear()
  {
      this->rr_.clear();
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::inverse()
  {
      // BUGBUG is this right? Does this handle icase correctly?
      basic_chset<Char> inv;
      inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
      inv -= *this;
      this->swap(inv);
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset<Char>::swap(basic_chset<Char> &that)
  {
      this->rr_.swap(that.rr_);
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset<Char> &
  basic_chset<Char>::operator |=(basic_chset<Char> const &that)
  {
      typedef typename range_run<Char>::const_iterator const_iterator;
      for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
      {
          this->rr_.set(*iter);
      }
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset<Char> &
  basic_chset<Char>::operator &=(basic_chset<Char> const &that)
  {
      basic_chset<Char> inv;
      inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
      inv -= that;
      *this -= inv;
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset<Char> &
  basic_chset<Char>::operator -=(basic_chset<Char> const &that)
  {
      typedef typename range_run<Char>::const_iterator const_iterator;
      for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
      {
          this->rr_.clear(*iter);
      }
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset<Char> &
  basic_chset<Char>::operator ^=(basic_chset<Char> const &that)
  {
      basic_chset bma = that;
      bma -= *this;
      *this -= that;
      *this |= bma;
      return *this;
  }
  
  #if(CHAR_BIT == 8)
  
  ///////////////////////////////////////////////////////////////////////////////
  //
  //  basic_chset: specializations for 8 bit chars using std::bitset
  //
  ///////////////////////////////////////////////////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char>::basic_chset_8bit()
  {
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char>::basic_chset_8bit(basic_chset_8bit<Char> const &arg)
    : bset_(arg.bset_)
  {
  }
  
  /////////////////////////////////
  template<typename Char>
  inline bool basic_chset_8bit<Char>::empty() const
  {
      return !this->bset_.any();
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline bool basic_chset_8bit<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
  {
      return this->bset_.test((unsigned char)v);
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline bool basic_chset_8bit<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
  {
      return this->bset_.test((unsigned char)tr.translate_nocase(v));
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::set(Char from, Char to)
  {
      for(int i = from; i <= to; ++i)
      {
          this->bset_.set((unsigned char)i);
      }
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset_8bit<Char>::set(Char from, Char to, Traits const &tr)
  {
      for(int i = from; i <= to; ++i)
      {
          this->bset_.set((unsigned char)tr.translate_nocase((Char)i));
      }
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::set(Char c)
  {
      this->bset_.set((unsigned char)c);
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset_8bit<Char>::set(Char c, Traits const &tr)
  {
      this->bset_.set((unsigned char)tr.translate_nocase(c));
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::clear(Char from, Char to)
  {
      for(int i = from; i <= to; ++i)
      {
          this->bset_.reset((unsigned char)i);
      }
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset_8bit<Char>::clear(Char from, Char to, Traits const &tr)
  {
      for(int i = from; i <= to; ++i)
      {
          this->bset_.reset((unsigned char)tr.translate_nocase((Char)i));
      }
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::clear(Char c)
  {
      this->bset_.reset((unsigned char)c);
  }
  
  /////////////////////////////////
  template<typename Char>
  template<typename Traits>
  inline void basic_chset_8bit<Char>::clear(Char c, Traits const &tr)
  {
      this->bset_.reset((unsigned char)tr.tranlsate_nocase(c));
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::clear()
  {
      this->bset_.reset();
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::inverse()
  {
      this->bset_.flip();
  }
  
  /////////////////////////////////
  template<typename Char>
  inline void basic_chset_8bit<Char>::swap(basic_chset_8bit<Char> &that)
  {
      std::swap(this->bset_, that.bset_);
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char> &
  basic_chset_8bit<Char>::operator |=(basic_chset_8bit<Char> const &that)
  {
      this->bset_ |= that.bset_;
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char> &
  basic_chset_8bit<Char>::operator &=(basic_chset_8bit<Char> const &that)
  {
      this->bset_ &= that.bset_;
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char> &
  basic_chset_8bit<Char>::operator -=(basic_chset_8bit<Char> const &that)
  {
      this->bset_ &= ~that.bset_;
      return *this;
  }
  
  /////////////////////////////////
  template<typename Char>
  inline basic_chset_8bit<Char> &
  basic_chset_8bit<Char>::operator ^=(basic_chset_8bit<Char> const &that)
  {
      this->bset_ ^= that.bset_;
      return *this;
  }
  
  template<typename Char>
  inline std::bitset<256> const &
  basic_chset_8bit<Char>::base() const
  {
      return this->bset_;
  }
  
  #endif // if(CHAR_BIT == 8)
  
  
  ///////////////////////////////////////////////////////////////////////////////
  // helpers
  template<typename Char, typename Traits>
  inline void set_char(basic_chset<Char> &chset, Char ch, Traits const &tr, bool icase)
  {
      icase ? chset.set(ch, tr) : chset.set(ch);
  }
  
  template<typename Char, typename Traits>
  inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase)
  {
      icase ? chset.set(from, to, tr) : chset.set(from, to);
  }
  
  template<typename Char, typename Traits>
  inline void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &tr)
  {
      BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(Char));
      for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
      {
          typedef typename std::char_traits<Char>::int_type int_type;
          Char ch = std::char_traits<Char>::to_char_type(static_cast<int_type>(i));
          if(no != tr.isctype(ch, char_class))
          {
              chset.set(ch);
          }
      }
  }
  
  }}} // namespace boost::xpressive::detail
  
  #endif
  
  