#include <iostream>
#include <stdexcept>
template<typename T>
constexpr T pack(bool b)
{
return b;
}
template<typename T, typename... Types>
constexpr T pack(bool b, Types... args)
{
static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
static_assert(sizeof(T) * 8 >= 1 + sizeof...(Types), "The pack type is not large enough to store the bits you have passed");
return (b << sizeof...(Types)) | pack<T>(args...);
}
template<typename T>
void unpack(T packed, bool& b)
{
b = packed & 1;
}
template<typename T, typename... Types>
void unpack(T packed, bool& b, Types&... args)
{
static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
static_assert(sizeof(T) * 8 >= 1 + sizeof...(Types), "The pack type is not large enough to provide the bits you have requested");
b = packed & (1 << sizeof...(Types));
unpack(packed, args...);
}
template<typename T, typename... Types>
void unpackChecked(T packed, bool& b, Types&... args)
{
static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
if(packed >= 1 + sizeof...(Types)) {
throw std::overflow_error(__PRETTY_FUNCTION__);
}
b = packed & (1 << sizeof...(Types));
unpack(packed, args...);
}
void printPackedUnpacked(int number) {
bool b0, b1;
unpack(number, b0, b1);
std::cout << "The number you entered was:" << pack<int>(b0, b1) << "\n";
}
void printPackedUnpackedChecked(int number) {
bool b0, b1;
unpackChecked(number, b0, b1);
std::cout << "The number you entered was:" << pack<int>(b0, b1) << "\n";
}
int main() {
std::cout << "Enter number: ";
int number;
std::cin >> number;
// Oops: no check if we have enough bits to represent the number
printPackedUnpacked(number);
//Ok, we check, but what if we decide to only use one bit and forget to
//update the check itself?
if(number < (1<<2))
printPackedUnpacked(number);
// now we don't need to update two places:
try {
printPackedUnpackedChecked(number);
} catch(const std::overflow_error &) {
std::cout << "The number you entered was to big to be processed!\n";
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkZXhjZXB0PgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY29uc3RleHByIFQgcGFjayhib29sIGIpCnsKICAgIHJldHVybiBiOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBUeXBlcz4KY29uc3RleHByIFQgcGFjayhib29sIGIsIFR5cGVzLi4uIGFyZ3MpCnsKICAgIHN0YXRpY19hc3NlcnQoc3RkOjppc19pbnRlZ3JhbDxUPjo6dmFsdWUsICJUaGUgcGFjayB0eXBlIGlzIG5vdCBhbiBpbnRlZ3JhbCB0eXBlIik7CiAgICBzdGF0aWNfYXNzZXJ0KHNpemVvZihUKSAqIDggPj0gMSArIHNpemVvZi4uLihUeXBlcyksICJUaGUgcGFjayB0eXBlIGlzIG5vdCBsYXJnZSBlbm91Z2ggdG8gc3RvcmUgdGhlIGJpdHMgeW91IGhhdmUgcGFzc2VkIik7CiAgICByZXR1cm4gKGIgPDwgc2l6ZW9mLi4uKFR5cGVzKSkgfCBwYWNrPFQ+KGFyZ3MuLi4pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIHVucGFjayhUIHBhY2tlZCwgYm9vbCYgYikKewogICAgYiA9IHBhY2tlZCAmIDE7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIFR5cGVzPgp2b2lkIHVucGFjayhUIHBhY2tlZCwgYm9vbCYgYiwgVHlwZXMmLi4uIGFyZ3MpCnsKICAgIHN0YXRpY19hc3NlcnQoc3RkOjppc19pbnRlZ3JhbDxUPjo6dmFsdWUsICJUaGUgcGFjayB0eXBlIGlzIG5vdCBhbiBpbnRlZ3JhbCB0eXBlIik7CiAgICBzdGF0aWNfYXNzZXJ0KHNpemVvZihUKSAqIDggPj0gMSArIHNpemVvZi4uLihUeXBlcyksICJUaGUgcGFjayB0eXBlIGlzIG5vdCBsYXJnZSBlbm91Z2ggdG8gcHJvdmlkZSB0aGUgYml0cyB5b3UgaGF2ZSByZXF1ZXN0ZWQiKTsKICAgIGIgPSBwYWNrZWQgJiAoMSA8PCBzaXplb2YuLi4oVHlwZXMpKTsKICAgIHVucGFjayhwYWNrZWQsIGFyZ3MuLi4pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBUeXBlcz4Kdm9pZCB1bnBhY2tDaGVja2VkKFQgcGFja2VkLCBib29sJiBiLCBUeXBlcyYuLi4gYXJncykKewogICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2ludGVncmFsPFQ+Ojp2YWx1ZSwgIlRoZSBwYWNrIHR5cGUgaXMgbm90IGFuIGludGVncmFsIHR5cGUiKTsKICAgIGlmKHBhY2tlZCA+PSAxICsgc2l6ZW9mLi4uKFR5cGVzKSkgewogICAgCXRocm93IHN0ZDo6b3ZlcmZsb3dfZXJyb3IoX19QUkVUVFlfRlVOQ1RJT05fXyk7CiAgICB9CiAgICBiID0gcGFja2VkICYgKDEgPDwgc2l6ZW9mLi4uKFR5cGVzKSk7CiAgICB1bnBhY2socGFja2VkLCBhcmdzLi4uKTsKfQoKdm9pZCBwcmludFBhY2tlZFVucGFja2VkKGludCBudW1iZXIpIHsKCWJvb2wgYjAsIGIxOwoJdW5wYWNrKG51bWJlciwgYjAsIGIxKTsKCXN0ZDo6Y291dCA8PCAiVGhlIG51bWJlciB5b3UgZW50ZXJlZCB3YXM6IiA8PCBwYWNrPGludD4oYjAsIGIxKSA8PCAiXG4iOwp9Cgp2b2lkIHByaW50UGFja2VkVW5wYWNrZWRDaGVja2VkKGludCBudW1iZXIpIHsKCWJvb2wgYjAsIGIxOwoJdW5wYWNrQ2hlY2tlZChudW1iZXIsIGIwLCBiMSk7CglzdGQ6OmNvdXQgPDwgIlRoZSBudW1iZXIgeW91IGVudGVyZWQgd2FzOiIgPDwgcGFjazxpbnQ+KGIwLCBiMSkgPDwgIlxuIjsKfQoKaW50IG1haW4oKSB7CglzdGQ6OmNvdXQgPDwgIkVudGVyIG51bWJlcjogIjsKCWludCBudW1iZXI7CglzdGQ6OmNpbiA+PiBudW1iZXI7CgkvLyBPb3BzOiBubyBjaGVjayBpZiB3ZSBoYXZlIGVub3VnaCBiaXRzIHRvIHJlcHJlc2VudCB0aGUgbnVtYmVyCglwcmludFBhY2tlZFVucGFja2VkKG51bWJlcik7CgkvL09rLCB3ZSBjaGVjaywgYnV0IHdoYXQgaWYgd2UgZGVjaWRlIHRvIG9ubHkgdXNlIG9uZSBiaXQgYW5kIGZvcmdldCB0byAKCS8vdXBkYXRlIHRoZSBjaGVjayBpdHNlbGY/CglpZihudW1iZXIgPCAoMTw8MikpCgkJcHJpbnRQYWNrZWRVbnBhY2tlZChudW1iZXIpOwoJLy8gbm93IHdlIGRvbid0IG5lZWQgdG8gdXBkYXRlIHR3byBwbGFjZXM6Cgl0cnkgewoJCXByaW50UGFja2VkVW5wYWNrZWRDaGVja2VkKG51bWJlcik7Cgl9IGNhdGNoKGNvbnN0IHN0ZDo6b3ZlcmZsb3dfZXJyb3IgJikgewoJCXN0ZDo6Y291dCA8PCAiVGhlIG51bWJlciB5b3UgZW50ZXJlZCB3YXMgdG8gYmlnIHRvIGJlIHByb2Nlc3NlZCFcbiI7Cgl9Cn0=