mfbt/EnumTypeTraits.h
author Geoff Brown <gbrown@mozilla.com>
Fri, 12 May 2017 15:18:38 -0600
changeset 406366 f0f6bd0a45434bcd6159ae9f7c4f558367332fe7
parent 354266 4088eddbb3397c248e50e9e8fba2a6faa0d85d5e
child 453817 1810b8f69bf358c3bf6c89d20d2a54b17cb8839f
permissions -rw-r--r--
Bug 1361732 - Mozharness support for a second virtualenv using python3; r=aki Currently Mozharness creates a Python 2.7 virtualenvironment with all the packages needed for Mozharness to run plus any applications that need to execute within it. For Talos, we now need a second Python virtual environment for mitmproxy, however, this package is for Python 3 and not for Python 2 (perhaps it could have worked). In any case, having the ability to support create Python 3 virtual environments will be handy. Specially since the approach of creating virtual environments is not by using 'virtualenv /path/to/venv' but by calling the venv module like 'python3 -m venv /path/to/venv'. The initial implementation only supports a list of modules. The following iteration will support requirement files and other parameters needed for pip and internal pypi hosts. Originally authored by armenzg.

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Type traits for enums. */

#ifndef mozilla_EnumTypeTraits_h
#define mozilla_EnumTypeTraits_h

#include <type_traits>

namespace mozilla {

namespace detail {

template<size_t EnumSize, bool EnumSigned, size_t StorageSize, bool StorageSigned>
struct EnumFitsWithinHelper;

// Signed enum, signed storage.
template<size_t EnumSize, size_t StorageSize>
struct EnumFitsWithinHelper<EnumSize, true, StorageSize, true>
  : public std::integral_constant<bool, (EnumSize <= StorageSize)>
{};

// Signed enum, unsigned storage.
template<size_t EnumSize, size_t StorageSize>
struct EnumFitsWithinHelper<EnumSize, true, StorageSize, false>
  : public std::integral_constant<bool, false>
{};

// Unsigned enum, signed storage.
template<size_t EnumSize, size_t StorageSize>
struct EnumFitsWithinHelper<EnumSize, false, StorageSize, true>
  : public std::integral_constant<bool, (EnumSize * 2 <= StorageSize)>
{};

// Unsigned enum, unsigned storage.
template<size_t EnumSize, size_t StorageSize>
struct EnumFitsWithinHelper<EnumSize, false, StorageSize, false>
  : public std::integral_constant<bool, (EnumSize <= StorageSize)>
{};

} // namespace detail

/*
 * Type trait that determines whether the enum type T can fit within the
 * integral type Storage without data loss. This trait should be used with
 * caution with an enum type whose underlying type has not been explicitly
 * specified: for such enums, the C++ implementation is free to choose a type
 * no smaller than int whose range encompasses all possible values of the enum.
 * So for an enum with only small non-negative values, the underlying type may
 * be either int or unsigned int, depending on the whims of the implementation.
 */
template<typename T, typename Storage>
struct EnumTypeFitsWithin
  : public detail::EnumFitsWithinHelper<
      sizeof(T),
      std::is_signed<typename std::underlying_type<T>::type>::value,
      sizeof(Storage),
      std::is_signed<Storage>::value
    >
{
  static_assert(std::is_enum<T>::value, "must provide an enum type");
  static_assert(std::is_integral<Storage>::value, "must provide an integral type");
};

} // namespace mozilla

#endif /* mozilla_EnumTypeTraits_h */