blob: fed3c519f801840c2ccf10735911310b3f1c3d48 [file] [log] [blame]
/*
* 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 <iterator>
#include <sstream>
#include <string>
#include <vector>
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<std::string>(result, " + "));
result << dynamic_.back();
return result.str();
}
std::vector<std::string> 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<std::string> dynamic_;
};