Ejemplo n.º 1
0
bool AliasIdSet::checkInvariants() const {
  if (isBigInteger()) {
    // Must use bitset mode for single integers below BitsetMax.
    return m_bits > BitsetMax && m_bits < Max;
  }
  return true;
}
Ejemplo n.º 2
0
uint32_t AliasIdSet::size() const {
  if (isBigInteger()) return 1;
  if (hasUpperRange()) return Max;

  // MSB is always set in bitset mode; it doesn't count.
  return folly::popcount(m_bits) - 1;
}
Ejemplo n.º 3
0
bool AliasIdSet::hasSingleValue() const {
  if (isBigInteger()) return true;
  if (hasUpperRange()) return false;

  auto const x = m_bits & (m_bits - 1);
  // popcount(x) = popcount(m_bits) - 1.
  return x == Empty;
}
Ejemplo n.º 4
0
void AliasIdSet::unset(uint32_t id) {
  if (isBigInteger()) {
    // Empty is represented in bitset mode.
    if (m_bits == id) m_bits = Empty;
    return;
  }
  // cannot safely unset upper range.
  if (id > BitsetMax) return;
  m_bits &= ~(1ull << id);
}
Ejemplo n.º 5
0
std::string AliasIdSet::toString() const {
  assertx(checkInvariants());

  if (isBigInteger()) {
    return folly::to<std::string>(m_bits);
  }
  if (empty()) return "None";
  if (isAny()) return "Any";

  std::string result;

  // Try to print the slots by grouping them, expect output like
  // '0~4,9,10,50~...'
  auto first = true;         // whether to avoid priting the separator
  int32_t begin = -1;        // starting bit of the consecutive range.

  // Append slots [begin, end) to result string.
  auto const appendRange = [&] (uint32_t end) {
    assertx(end > begin);
    result += folly::to<std::string>(begin);
    if (end == begin + 1) return;
    if (end == begin + 2) {
      result += folly::to<std::string>(",", begin + 1);
    } else {
      result += folly::to<std::string>("~", end - 1);
    }
  };

  for (uint32_t i = 0; i <= BitsetMax; ++i) {
    if (test(i)) {
      if (begin < 0) begin = static_cast<int32_t>(i);
      else continue;
    } else {
      if (begin < 0) continue;
      if (!first) result += ",";
      appendRange(i);
      begin = -1;
      first = false;
    }
  }

  if (hasUpperRange()) {
    if (!first) result += ",";
    if (begin < 0) begin = BitsetMax + 1;
    result += folly::to<std::string>(begin, "~...");
  } else if (begin >= 0) {
    // Append [begin, BitsetMax].
    appendRange(BitsetMax + 1);
  }

  return result;
}
Ejemplo n.º 6
0
bool AliasIdSet::isSubsetOf(const AliasIdSet rhs) const {
  if (*this == rhs || empty()) return true;

  if (isBigInteger()) {
    // If `rhs' is a big integer, the following will return false. We know
    // they cannot be the same integer.
    return rhs.hasUpperRange();
  }

  // nonempty bitset.
  if (rhs.isBigInteger()) return false;

  // Both are bitsets.
  return !(m_bits & (~rhs.m_bits));
}
Ejemplo n.º 7
0
bool AliasIdSet::maybe(const AliasIdSet other) const {
  if (isBigInteger()) {
    if (m_bits == other.m_bits) return true;
    // If `other' is a big integer, the following will return false.
    return other.hasUpperRange();
  }

  if (other.isBigInteger()) {
    return hasUpperRange();
  }

  // Both are bitsets, including cases when one is empty.
  auto r = m_bits & other.m_bits;
  // Does r have a bit set other than MSB?
  return r & (r - 1);
}
Ejemplo n.º 8
0
AliasIdSet AliasIdSet::operator|=(const AliasIdSet rhs) {
  if (*this == rhs || rhs.empty()) return *this;
  if (empty()) {
    m_bits = rhs.m_bits;
    return *this;
  }

  if (isBigInteger() || rhs.isBigInteger()) {
    // Result contains a big integer, as well as one other integer, so we
    // must use bitset mode.
    setUpperRange();
  }

  if (rhs.isBitset()) {
    // Both are bitsets.
    m_bits |= rhs.m_bits;
  }

  assertx(checkInvariants());
  return *this;
}
Ejemplo n.º 9
0
std::string CborValue::inspect() const
{
    if( isNull() )
    {
        static std::string null = "(null)";
        return null;
    }
    else if( isUndefined() )
    {
        static std::string undefined = "(undefined)";
        return undefined;
    }
    else if( isBool() )
    {
        return boost::lexical_cast<std::string>(toBool());
    }
    else if( isPositiveInteger() )
    {
        return boost::lexical_cast<std::string>(toPositiveInteger());
    }
    else if( isNegativeInteger() )
    {
        std::string result = "-";
        const char specialValue[] = "18446744073709551616"; // 0x10000000000000000
        uint64_t value = toNegativeInteger();

        if( value == 0 )
            result += specialValue;
        else
            result += boost::lexical_cast<std::string>(value);

        return result;
    }
    else if( isDouble() )
    {
        return boost::lexical_cast<std::string>(toDouble());
    }
    else if( isString() )
    {
        return toString();
    }
    else if( isByteString() )
    {
        std::vector<char> byteString = toByteString();
        std::string result = "(0x";

        static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                                     'A', 'B', 'C', 'D', 'E', 'F'};

        for(size_t i = 0; i < byteString.size(); ++i)
        {
            unsigned char c = static_cast<unsigned char>(byteString[i]);

            result += hex[c / sizeof(hex)];
            result += hex[c % sizeof(hex)];
        }

        result += ')';
        return result;
    }
    else if( isArray() )
    {
        std::vector<CborValue> values = toArray();
        std::string result = "[";

        if( values.empty() == false )
        {
            for(size_t i = 0; i < values.size(); ++i)
            {
                result += values[i].inspect();
                result += ", ";
            }

            result.resize(result.size() - 1);
            result[result.size() - 1] = ']';
        }
        else
        {
            result += ']';
        }

        return result;
    }
    else if( isMap() )
    {
        std::map<CborValue, CborValue> values = toMap();
        std::string result = "{";

        if( values.empty() == false )
        {
            std::map<CborValue, CborValue>::iterator it = values.begin();
            std::map<CborValue, CborValue>::iterator end = values.end();

            for(; it != end; ++it)
            {
                result += it->first.inspect();
                result += ": ";
                result += it->second.inspect();
                result += ", ";
            }

            result.resize(result.size() - 1);
            result[result.size() - 1] = '}';
        }
        else
        {
            result += '}';
        }

        return result;
    }
    else if( isBigInteger() )
    {
        BigInteger bigInteger = toBigInteger();
        std::string result;

        if( bigInteger.positive )
            result = "(big integer: 0x";
        else
            result = "(negative big integer: 0x";

        static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                                     'A', 'B', 'C', 'D', 'E', 'F'};

        if( bigInteger.bigint.empty() == false )
        {
            for(size_t i = 0; i < bigInteger.bigint.size(); ++i)
            {
                unsigned char c = static_cast<unsigned char >(bigInteger.bigint[i]);

                result += hex[c / sizeof(hex)];
                result += hex[c % sizeof(hex)];
            }

            result.resize(result.size() - 1);
            result[result.size() - 1] = ')';
        }
        else
        {
            result += ')';
        }

        return result;
    }

    assert(false);
    std::string invalidType = "(invalid type)";
    return invalidType;
}