text: /*
  	This file is part of solidity.
  
  	solidity is free software: you can redistribute it and/or modify
  	it under the terms of the GNU General Public License as published by
  	the Free Software Foundation, either version 3 of the License, or
  	(at your option) any later version.
  
  	solidity is distributed in the hope that it will be useful,
  	but WITHOUT ANY WARRANTY; without even the implied warranty of
  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  	GNU General Public License for more details.
  
  	You should have received a copy of the GNU General Public License
  	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
  */
  /** @file Common.h
   * @author Gav Wood <i@gavwood.com>
   * @date 2014
   *
   * Very common stuff (i.e. that every other header needs except vector_ref.h).
   */
  
  #pragma once
  
  // way too many unsigned to size_t warnings in 32 bit build
  #ifdef _M_IX86
  #pragma warning(disable:4244)
  #endif
  
  #if _MSC_VER && _MSC_VER < 1900
  #define _ALLOW_KEYWORD_MACROS
  #define noexcept throw()
  #endif
  
  #ifdef __INTEL_COMPILER
  #pragma warning(disable:3682) //call through incomplete class
  #endif
  
  #include <map>
  #include <unordered_map>
  #include <vector>
  #include <set>
  #include <unordered_set>
  #include <functional>
  #include <string>
  #include <chrono>
  
  #include <boost/multiprecision/cpp_int.hpp>
  
  #include "vector_ref.h"
  
  using byte = uint8_t;
  
  // Quote a given token stream to turn it into a string.
  #define DEV_QUOTED_HELPER(s) #s
  #define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)
  
  namespace dev
  {
  
  // Binary data types.
  using bytes = std::vector<byte>;
  using bytesRef = vector_ref<byte>;
  using bytesConstRef = vector_ref<byte const>;
  
  // Numeric types.
  using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
  using u64 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
  using u128 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
  using s128 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
  using u256 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
  using s256 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
  using u160 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
  using s160 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
  using u512 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
  using s512 =  boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
  using u256s = std::vector<u256>;
  using u160s = std::vector<u160>;
  using u256Set = std::set<u256>;
  using u160Set = std::set<u160>;
  
  // Map types.
  using StringMap = std::map<std::string, std::string>;
  
  // Hash types.
  using StringHashMap = std::unordered_map<std::string, std::string>;
  
  // String types.
  using strings = std::vector<std::string>;
  // Fixed-length string types.
  using string32 = std::array<char, 32>;
  
  // Null/Invalid values for convenience.
  static const bytes NullBytes;
  
  /// Interprets @a _u as a two's complement signed number and returns the resulting s256.
  inline s256 u2s(u256 _u)
  {
  	static const bigint c_end = bigint(1) << 256;
  	if (boost::multiprecision::bit_test(_u, 255))
  		return s256(-(c_end - _u));
  	else
  		return s256(_u);
  }
  
  /// Interprets @a _u as a two's complement signed number and returns the resulting s128.
  inline s128 u2s128(u128 _u)
  {
  	static const bigint c_end = bigint(1) << 128;
  	if (boost::multiprecision::bit_test(_u, 127))
  		return s128(-(c_end - _u));
  	else
  		return s128(_u);
  }
  
  /// @returns the two's complement signed representation of the signed number _u.
  inline u256 s2u(s256 _u)
  {
  	static const bigint c_end = bigint(1) << 256;
      if (_u >= 0)
  		return u256(_u);
      else
  		return u256(c_end + _u);
  }
  
  /// @returns the two's complement signed representation of the signed number _u.
  inline u128 s2u128(s128 _u)
  {
  	static const bigint c_end = bigint(1) << 128;
      if (_u >= 0)
  		return u128(_u);
      else
  		return u128(c_end + _u);
  }
  
  inline std::ostream& operator<<(std::ostream& os, bytes const& _bytes)
  {
  	std::ostringstream ss;
  	ss << std::hex;
  	std::copy(_bytes.begin(), _bytes.end(), std::ostream_iterator<int>(ss, ","));
  	std::string result = ss.str();
  	result.pop_back();
  	os << "[" + result + "]";
  	return os;
  }
  
  template <size_t n> inline u256 exp10()
  {
  	return exp10<n - 1>() * u256(10);
  }
  
  template <> inline u256 exp10<0>()
  {
  	return u256(1);
  }
  
  /// RAII utility class whose destructor calls a given function.
  class ScopeGuard
  {
  public:
  	ScopeGuard(std::function<void(void)> _f): m_f(_f) {}
  	~ScopeGuard() { m_f(); }
  
  private:
  	std::function<void(void)> m_f;
  };
  
  enum class WithExisting: int
  {
  	Trust = 0,
  	Verify,
  	Rescue,
  	Kill
  };
  
  }
  