| 157 | namespace { |
| 158 | |
| 159 | std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) { |
| 160 | // Select a divisor which is the largest power of the base < 2^64. |
| 161 | uint128 div; |
| 162 | int div_base_log; |
| 163 | switch (flags & std::ios::basefield) { |
| 164 | case std::ios::hex: |
| 165 | div = 0x1000000000000000; // 16^15 |
| 166 | div_base_log = 15; |
| 167 | break; |
| 168 | case std::ios::oct: |
| 169 | div = 01000000000000000000000; // 8^21 |
| 170 | div_base_log = 21; |
| 171 | break; |
| 172 | default: // std::ios::dec |
| 173 | div = 10000000000000000000u; // 10^19 |
| 174 | div_base_log = 19; |
| 175 | break; |
| 176 | } |
| 177 | |
| 178 | // Now piece together the uint128 representation from three chunks of the |
| 179 | // original value, each less than "div" and therefore representable as a |
| 180 | // uint64_t. |
| 181 | std::ostringstream os; |
| 182 | std::ios_base::fmtflags copy_mask = |
| 183 | std::ios::basefield | std::ios::showbase | std::ios::uppercase; |
| 184 | os.setf(flags & copy_mask, copy_mask); |
| 185 | uint128 high = v; |
| 186 | uint128 low; |
| 187 | DivModImpl(high, div, &high, &low); |
| 188 | uint128 mid; |
| 189 | DivModImpl(high, div, &high, &mid); |
| 190 | if (Uint128Low64(high) != 0) { |
| 191 | os << Uint128Low64(high); |
| 192 | os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); |
| 193 | os << Uint128Low64(mid); |
| 194 | os << std::setw(div_base_log); |
| 195 | } else if (Uint128Low64(mid) != 0) { |
| 196 | os << Uint128Low64(mid); |
| 197 | os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); |
| 198 | } |
| 199 | os << Uint128Low64(low); |
| 200 | return os.str(); |
| 201 | } |
| 202 | |
| 203 | } // namespace |
| 204 |
no test coverage detected