/* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include class Size { public: Size() {} Size(int bits) { is_valid_ = true; bits_ = bits; } Size(std::string dynamic) { is_valid_ = true; dynamic_.push_back(dynamic); } Size(int bits, std::string dynamic) { is_valid_ = true; bits_ = bits; dynamic_.push_back(dynamic); } Size(const Size& size) { is_valid_ = size.is_valid_; bits_ = size.bits_; dynamic_ = size.dynamic_; } std::string dynamic_string() const { if (dynamic_.empty()) return "0"; std::stringstream result; // Print everything but the last element then append it manually to avoid // the trailing "+" operator. std::copy(dynamic_.begin(), dynamic_.end() - 1, std::ostream_iterator(result, " + ")); result << dynamic_.back(); return result.str(); } std::vector dynamic_string_list() { return dynamic_; } bool empty() const { return !is_valid_; } bool has_bits() const { return bits_ != 0; } bool has_dynamic() const { return !dynamic_.empty(); } int bits() const { return bits_; } int bytes() const { // Round up to the nearest byte return (bits_ + 7) / 8; } Size operator+(int rhs) { return Size(bits_ + rhs); } Size operator+(std::string rhs) { auto ret = Size(); ret.is_valid_ = true; ret.dynamic_.insert(ret.dynamic_.end(), dynamic_.begin(), dynamic_.end()); ret.dynamic_.push_back(rhs); return ret; } Size operator+(const Size& rhs) { auto ret = Size(bits_ + rhs.bits_); ret.is_valid_ = is_valid_ && rhs.is_valid_; ret.dynamic_.insert(ret.dynamic_.end(), dynamic_.begin(), dynamic_.end()); ret.dynamic_.insert(ret.dynamic_.end(), rhs.dynamic_.begin(), rhs.dynamic_.end()); return ret; } Size& operator+=(int rhs) { is_valid_ = true; bits_ += rhs; return *this; } Size& operator+=(std::string rhs) { is_valid_ = true; dynamic_.push_back(rhs); return *this; } Size& operator+=(const Size& rhs) { is_valid_ = is_valid_ && rhs.is_valid_; bits_ += rhs.bits_; dynamic_.insert(dynamic_.end(), rhs.dynamic_.begin(), rhs.dynamic_.end()); return *this; } std::string ToString() const { std::stringstream str; str << "/* Bits: */ " << bits_ << " + /* Dynamic: */ " << dynamic_string(); if (!is_valid_) { str << " (invalid) "; } return str.str(); } friend std::ostream& operator<<(std::ostream& os, const Size& rhs) { return os << rhs.ToString(); } private: bool is_valid_ = false; int bits_ = 0; std::vector dynamic_; };