1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <iterator> 20 #include <sstream> 21 #include <string> 22 #include <vector> 23 24 class Size { 25 public: Size()26 Size() {} 27 Size(int bits)28 Size(int bits) { 29 is_valid_ = true; 30 bits_ = bits; 31 } 32 Size(std::string dynamic)33 Size(std::string dynamic) { 34 is_valid_ = true; 35 dynamic_.push_back(dynamic); 36 } 37 Size(int bits,std::string dynamic)38 Size(int bits, std::string dynamic) { 39 is_valid_ = true; 40 bits_ = bits; 41 dynamic_.push_back(dynamic); 42 } 43 Size(const Size & size)44 Size(const Size& size) { 45 is_valid_ = size.is_valid_; 46 bits_ = size.bits_; 47 dynamic_ = size.dynamic_; 48 } 49 dynamic_string()50 std::string dynamic_string() const { 51 if (dynamic_.empty()) return "0"; 52 53 std::stringstream result; 54 // Print everything but the last element then append it manually to avoid 55 // the trailing "+" operator. 56 std::copy(dynamic_.begin(), dynamic_.end() - 1, std::ostream_iterator<std::string>(result, " + ")); 57 result << dynamic_.back(); 58 return result.str(); 59 } 60 dynamic_string_list()61 std::vector<std::string> dynamic_string_list() { 62 return dynamic_; 63 } 64 empty()65 bool empty() const { 66 return !is_valid_; 67 } 68 has_bits()69 bool has_bits() const { 70 return bits_ != 0; 71 } 72 has_dynamic()73 bool has_dynamic() const { 74 return !dynamic_.empty(); 75 } 76 bits()77 int bits() const { 78 return bits_; 79 } 80 bytes()81 int bytes() const { 82 // Round up to the nearest byte 83 return (bits_ + 7) / 8; 84 } 85 86 Size operator+(int rhs) { 87 return Size(bits_ + rhs); 88 } 89 90 Size operator+(std::string rhs) { 91 auto ret = Size(); 92 ret.is_valid_ = true; 93 ret.dynamic_.insert(ret.dynamic_.end(), dynamic_.begin(), dynamic_.end()); 94 ret.dynamic_.push_back(rhs); 95 return ret; 96 } 97 98 Size operator+(const Size& rhs) { 99 auto ret = Size(bits_ + rhs.bits_); 100 ret.is_valid_ = is_valid_ && rhs.is_valid_; 101 ret.dynamic_.insert(ret.dynamic_.end(), dynamic_.begin(), dynamic_.end()); 102 ret.dynamic_.insert(ret.dynamic_.end(), rhs.dynamic_.begin(), rhs.dynamic_.end()); 103 return ret; 104 } 105 106 Size& operator+=(int rhs) { 107 is_valid_ = true; 108 bits_ += rhs; 109 return *this; 110 } 111 112 Size& operator+=(std::string rhs) { 113 is_valid_ = true; 114 dynamic_.push_back(rhs); 115 return *this; 116 } 117 118 Size& operator+=(const Size& rhs) { 119 is_valid_ = is_valid_ && rhs.is_valid_; 120 bits_ += rhs.bits_; 121 dynamic_.insert(dynamic_.end(), rhs.dynamic_.begin(), rhs.dynamic_.end()); 122 return *this; 123 } 124 ToString()125 std::string ToString() const { 126 std::stringstream str; 127 str << "/* Bits: */ " << bits_ << " + /* Dynamic: */ " << dynamic_string(); 128 if (!is_valid_) { 129 str << " (invalid) "; 130 } 131 return str.str(); 132 } 133 134 friend std::ostream& operator<<(std::ostream& os, const Size& rhs) { 135 return os << rhs.ToString(); 136 } 137 138 private: 139 bool is_valid_ = false; 140 int bits_ = 0; 141 std::vector<std::string> dynamic_; 142 }; 143