#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
#include <chrono>
#include <type_traits>
template<bool B>
using BoolType = std::integral_constant<bool, B >;
template<char C> struct IsNumber : BoolType<(C >= '0' && C <= '9')>{};
template<char C> struct IsLower : BoolType<(C >= 'a' && C <= 'f')>{};
template<char C> struct IsUpper : BoolType<(C >= 'A' && C <= 'F')>{};
template<char C> struct ToNibble : std::integral_constant<unsigned char,
IsNumber<C>::value ? C-'0' : IsLower<C>::value ? (C-'a') +10 : IsUpper<C>::value ? (C-'A') +10 : 0xFF
>{};
template<unsigned char...> struct Sequence{};
template<int I, typename T> struct MakeSequence;
template<int I, unsigned char... Cs> struct MakeSequence<I,Sequence<Cs...>>:
MakeSequence<I+1, Sequence<Cs...,ToNibble<I>::value>>{};
template<unsigned char... Cs> struct MakeSequence<256,Sequence<Cs...>>{
using Type = Sequence<Cs...>;
};
template<typename T> struct HexASCIITable;
template<unsigned char... Cs> struct HexASCIITable<Sequence<Cs...>>{
static unsigned char convert(const char c){
static const unsigned char table[256] = {Cs...};
return table[static_cast<int>(c)];
}
};
using Table = HexASCIITable<typename MakeSequence<0,Sequence<>>::Type>;
class ToHexIterator : public std::iterator<std::input_iterator_tag, unsigned char>{
char* it_;
char* end_;
unsigned char current_;
void skipInvalid(){ while (Table::convert(*it_) == 0xFF && it_ != end_){ ++it_; }; }
public:
ToHexIterator() :it_{ nullptr }, end_{ nullptr }, current_{}{} //default constructed means end iterator
ToHexIterator(char* begin, char* end) :it_{ begin }, end_{ end }, current_{}{
skipInvalid(); //make sure we are pointing to valid stuff
++(*this);
}
bool operator==(const ToHexIterator &other){
return it_ == nullptr && end_ == nullptr && other.it_ == nullptr && other.end_ == nullptr;
}
bool operator!=(const ToHexIterator &other){
return !(*this == other);
}
unsigned char operator*(){
return current_;
}
ToHexIterator & operator++(){
current_ = 0;
if (it_ != end_) {
do{
current_ <<= 4;
current_ += Table::convert(*it_);
++it_;
} while (Table::convert(*it_) != 0xFF && it_ != end_);
skipInvalid();
}
else {
it_ = nullptr;
end_ = nullptr;
}
return *this;
}
ToHexIterator operator++(int){
ToHexIterator temp(*this);
++(*this);
return temp;
}
};
void __attribute__ ((noinline)) test1(std::vector<unsigned char> &v){
char in[] = "1,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10";
std::copy(ToHexIterator{ std::begin(in), std::end(in) }, ToHexIterator{}, std::back_inserter(v));
}
void __attribute__ ((noinline)) test2(std::vector<unsigned char> &v){
std::istringstream iss("1,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10,3,8,b,e,ff,10");
unsigned int num = 0;
while(iss >> std::hex >> num || !iss.eof())
{
if(iss.fail())
{
iss.clear();
char dummy;
iss >> dummy;
continue;
}
if(num <= 0xff) {
v.push_back(num);
}
else {
// Error single byte value expected
}
}
}
int main() {
std::vector<unsigned char> dataValues;
std::vector<unsigned char> dataValues2;
std::chrono::nanoseconds time[2]{{},{}};
for(int i=0;i<100;i++){
const auto t1 = std::chrono::high_resolution_clock::now();
test2(dataValues2);
const auto t2 = std::chrono::high_resolution_clock::now();
time[0] += t2 - t1;
const auto t3 = std::chrono::high_resolution_clock::now();
test1(dataValues);
const auto t4 = std::chrono::high_resolution_clock::now();
time[1] += t4 - t3;
}
typedef std::chrono::nanoseconds output_time;
const char* const out_unit = " ns";
std::cout << "1: " << std::chrono::duration_cast<output_time>(time[0]).count() << out_unit << "\n";
std::cout << "2: " << std::chrono::duration_cast<output_time>(time[1]).count() << out_unit << "\n";
std::cout << std::hex << std::setfill('0');
for(int i=0;i<6;i++){
std::cout << "0x" << std::setw(2) << static_cast<unsigned int>(dataValues2[i]) << std::endl;
std::cout << "0x" << std::setw(2) << static_cast<unsigned int>(dataValues[i]) << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHNzdHJlYW0+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnRlbXBsYXRlPGJvb2wgQj4KdXNpbmcgQm9vbFR5cGUgPSBzdGQ6OmludGVncmFsX2NvbnN0YW50PGJvb2wsIEIgPjsKCnRlbXBsYXRlPGNoYXIgQz4gc3RydWN0IElzTnVtYmVyIDogQm9vbFR5cGU8KEMgPj0gJzAnICYmIEMgPD0gJzknKT57fTsKdGVtcGxhdGU8Y2hhciBDPiBzdHJ1Y3QgSXNMb3dlciA6IEJvb2xUeXBlPChDID49ICdhJyAmJiBDIDw9ICdmJyk+e307CnRlbXBsYXRlPGNoYXIgQz4gc3RydWN0IElzVXBwZXIgOiBCb29sVHlwZTwoQyA+PSAnQScgJiYgQyA8PSAnRicpPnt9Owp0ZW1wbGF0ZTxjaGFyIEM+IHN0cnVjdCBUb05pYmJsZSA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8dW5zaWduZWQgY2hhciwKCUlzTnVtYmVyPEM+Ojp2YWx1ZSA/IEMtJzAnIDogSXNMb3dlcjxDPjo6dmFsdWUgPyAoQy0nYScpICsxMCA6IElzVXBwZXI8Qz46OnZhbHVlID8gKEMtJ0EnKSArMTAgOiAweEZGCj57fTsKdGVtcGxhdGU8dW5zaWduZWQgY2hhci4uLj4gc3RydWN0IFNlcXVlbmNle307CnRlbXBsYXRlPGludCBJLCB0eXBlbmFtZSBUPiBzdHJ1Y3QgTWFrZVNlcXVlbmNlOwp0ZW1wbGF0ZTxpbnQgSSwgdW5zaWduZWQgY2hhci4uLiBDcz4gc3RydWN0IE1ha2VTZXF1ZW5jZTxJLFNlcXVlbmNlPENzLi4uPj46CglNYWtlU2VxdWVuY2U8SSsxLCBTZXF1ZW5jZTxDcy4uLixUb05pYmJsZTxJPjo6dmFsdWU+Pnt9Owp0ZW1wbGF0ZTx1bnNpZ25lZCBjaGFyLi4uIENzPiBzdHJ1Y3QgTWFrZVNlcXVlbmNlPDI1NixTZXF1ZW5jZTxDcy4uLj4+ewkKCXVzaW5nIFR5cGUgPSBTZXF1ZW5jZTxDcy4uLj47IAp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgSGV4QVNDSUlUYWJsZTsKdGVtcGxhdGU8dW5zaWduZWQgY2hhci4uLiBDcz4gc3RydWN0IEhleEFTQ0lJVGFibGU8U2VxdWVuY2U8Q3MuLi4+PnsKCXN0YXRpYyB1bnNpZ25lZCBjaGFyIGNvbnZlcnQoY29uc3QgY2hhciBjKXsKCQlzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciB0YWJsZVsyNTZdID0ge0NzLi4ufTsKCQlyZXR1cm4gdGFibGVbc3RhdGljX2Nhc3Q8aW50PihjKV07Cgl9Cn07Cgp1c2luZyBUYWJsZSA9IEhleEFTQ0lJVGFibGU8dHlwZW5hbWUgTWFrZVNlcXVlbmNlPDAsU2VxdWVuY2U8Pj46OlR5cGU+OwoKY2xhc3MgVG9IZXhJdGVyYXRvciA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6aW5wdXRfaXRlcmF0b3JfdGFnLCB1bnNpZ25lZCBjaGFyPnsKICAgIGNoYXIqIGl0XzsKICAgIGNoYXIqIGVuZF87CiAgICB1bnNpZ25lZCBjaGFyIGN1cnJlbnRfOwogICAgdm9pZCBza2lwSW52YWxpZCgpeyB3aGlsZSAoVGFibGU6OmNvbnZlcnQoKml0XykgPT0gMHhGRiAmJiBpdF8gIT0gZW5kXyl7ICsraXRfOyB9OyB9CnB1YmxpYzoKICAgIFRvSGV4SXRlcmF0b3IoKSA6aXRfeyBudWxscHRyIH0sIGVuZF97IG51bGxwdHIgfSwgY3VycmVudF97fXt9ICAgICAgICAgICAgICAgICAgLy9kZWZhdWx0IGNvbnN0cnVjdGVkIG1lYW5zIGVuZCBpdGVyYXRvcgogICAgVG9IZXhJdGVyYXRvcihjaGFyKiBiZWdpbiwgY2hhciogZW5kKSA6aXRfeyBiZWdpbiB9LCBlbmRfeyBlbmQgfSwgY3VycmVudF97fXsKICAgICAgICBza2lwSW52YWxpZCgpOyAgLy9tYWtlIHN1cmUgd2UgYXJlIHBvaW50aW5nIHRvIHZhbGlkIHN0dWZmCiAgICAgICAgKysoKnRoaXMpOwogICAgfQogICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFRvSGV4SXRlcmF0b3IgJm90aGVyKXsKICAgICAgICByZXR1cm4gaXRfID09IG51bGxwdHIgJiYgZW5kXyA9PSBudWxscHRyICYmIG90aGVyLml0XyA9PSBudWxscHRyICYmIG90aGVyLmVuZF8gPT0gbnVsbHB0cjsKICAgIH0KICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBUb0hleEl0ZXJhdG9yICZvdGhlcil7CiAgICAgICAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwogICAgfQogICAgdW5zaWduZWQgY2hhciBvcGVyYXRvciooKXsKICAgICAgICByZXR1cm4gY3VycmVudF87CiAgICB9CiAgICBUb0hleEl0ZXJhdG9yICYgb3BlcmF0b3IrKygpewogICAgICAgIGN1cnJlbnRfID0gMDsKICAgICAgICBpZiAoaXRfICE9IGVuZF8pIHsKICAgICAgICAgICAgZG97CiAgICAgICAgICAgIAljdXJyZW50XyA8PD0gNDsKICAgICAgICAgICAgICAgIGN1cnJlbnRfICs9IFRhYmxlOjpjb252ZXJ0KCppdF8pOwogICAgICAgICAgICAgICAgKytpdF87CiAgICAgICAgICAgIH0gd2hpbGUgKFRhYmxlOjpjb252ZXJ0KCppdF8pICE9IDB4RkYgJiYgaXRfICE9IGVuZF8pOwogICAgICAgICAgICBza2lwSW52YWxpZCgpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaXRfID0gbnVsbHB0cjsKICAgICAgICAgICAgZW5kXyA9IG51bGxwdHI7CiAgICAgICAgfQogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KICAgIFRvSGV4SXRlcmF0b3Igb3BlcmF0b3IrKyhpbnQpewogICAgICAgIFRvSGV4SXRlcmF0b3IgdGVtcCgqdGhpcyk7CiAgICAgICAgKysoKnRoaXMpOwogICAgICAgIHJldHVybiB0ZW1wOwogICAgfQp9OwoKdm9pZCBfX2F0dHJpYnV0ZV9fICgobm9pbmxpbmUpKSB0ZXN0MShzdGQ6OnZlY3Rvcjx1bnNpZ25lZCBjaGFyPiAmdil7CgljaGFyIGluW10gPSAiMSwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwIjsKCXN0ZDo6Y29weShUb0hleEl0ZXJhdG9yeyBzdGQ6OmJlZ2luKGluKSwgc3RkOjplbmQoaW4pIH0sIFRvSGV4SXRlcmF0b3J7fSwgc3RkOjpiYWNrX2luc2VydGVyKHYpKTsKfQoKdm9pZCBfX2F0dHJpYnV0ZV9fICgobm9pbmxpbmUpKSB0ZXN0MihzdGQ6OnZlY3Rvcjx1bnNpZ25lZCBjaGFyPiAmdil7CglzdGQ6OmlzdHJpbmdzdHJlYW0gaXNzKCIxLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAsMyw4LGIsZSxmZiwxMCwzLDgsYixlLGZmLDEwLDMsOCxiLGUsZmYsMTAiKTsKICAgIHVuc2lnbmVkIGludCBudW0gPSAwOwogICAgd2hpbGUoaXNzID4+IHN0ZDo6aGV4ID4+IG51bSB8fCAhaXNzLmVvZigpKSAKICAgIHsKICAgICAgICBpZihpc3MuZmFpbCgpKSAKICAgICAgICB7CiAgICAgICAgICAgIGlzcy5jbGVhcigpOwogICAgICAgICAgICBjaGFyIGR1bW15OwogICAgICAgICAgICBpc3MgPj4gZHVtbXk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZihudW0gPD0gMHhmZikgewogICAgICAgICAgICB2LnB1c2hfYmFjayhudW0pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAJLy8gRXJyb3Igc2luZ2xlIGJ5dGUgdmFsdWUgZXhwZWN0ZWQKICAgICAgICB9CiAgICB9CQp9CgppbnQgbWFpbigpIHsKCiAgICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZCBjaGFyPiBkYXRhVmFsdWVzOwogICAgc3RkOjp2ZWN0b3I8dW5zaWduZWQgY2hhcj4gZGF0YVZhbHVlczI7CiAgICAKICAgIAlzdGQ6OmNocm9ubzo6bmFub3NlY29uZHMgdGltZVsyXXt7fSx7fX07CgoJZm9yKGludCBpPTA7aTwxMDA7aSsrKXsKCQljb25zdCBhdXRvIHQxID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CgkJdGVzdDIoZGF0YVZhbHVlczIpOwoJCWNvbnN0IGF1dG8gdDIgPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKCQl0aW1lWzBdICs9IHQyIC0gdDE7CgkJY29uc3QgYXV0byB0MyA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOwoJCXRlc3QxKGRhdGFWYWx1ZXMpOwoJCWNvbnN0IGF1dG8gdDQgPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKCQl0aW1lWzFdICs9IHQ0IC0gdDM7Cgl9CgoJdHlwZWRlZiBzdGQ6OmNocm9ubzo6bmFub3NlY29uZHMgb3V0cHV0X3RpbWU7Cgljb25zdCBjaGFyKiBjb25zdCBvdXRfdW5pdCA9ICIgbnMiOwoKCXN0ZDo6Y291dCA8PCAiMTogIiA8PCBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxvdXRwdXRfdGltZT4odGltZVswXSkuY291bnQoKSA8PCBvdXRfdW5pdCA8PCAiXG4iOwoJc3RkOjpjb3V0IDw8ICIyOiAiIDw8IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0PG91dHB1dF90aW1lPih0aW1lWzFdKS5jb3VudCgpIDw8IG91dF91bml0IDw8ICJcbiI7CgkKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmhleCA8PCBzdGQ6OnNldGZpbGwoJzAnKTsKICAgIGZvcihpbnQgaT0wO2k8NjtpKyspewogICAgCXN0ZDo6Y291dCA8PCAiMHgiIDw8IHN0ZDo6c2V0dygyKSA8PCBzdGF0aWNfY2FzdDx1bnNpZ25lZCBpbnQ+KGRhdGFWYWx1ZXMyW2ldKSA8PCBzdGQ6OmVuZGw7CiAgICAJc3RkOjpjb3V0IDw8ICIweCIgPDwgc3RkOjpzZXR3KDIpIDw8IHN0YXRpY19jYXN0PHVuc2lnbmVkIGludD4oZGF0YVZhbHVlc1tpXSkgPDwgc3RkOjplbmRsOwogICAgfQoJcmV0dXJuIDA7Cn0=