fork download
  1. #include <iostream>
  2. #include <stdexcept>
  3.  
  4. template<typename T>
  5. constexpr T pack(bool b)
  6. {
  7. return b;
  8. }
  9.  
  10. template<typename T, typename... Types>
  11. constexpr T pack(bool b, Types... args)
  12. {
  13. static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
  14. static_assert(sizeof(T) * 8 >= 1 + sizeof...(Types), "The pack type is not large enough to store the bits you have passed");
  15. return (b << sizeof...(Types)) | pack<T>(args...);
  16. }
  17.  
  18. template<typename T>
  19. void unpack(T packed, bool& b)
  20. {
  21. b = packed & 1;
  22. }
  23.  
  24. template<typename T, typename... Types>
  25. void unpack(T packed, bool& b, Types&... args)
  26. {
  27. static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
  28. static_assert(sizeof(T) * 8 >= 1 + sizeof...(Types), "The pack type is not large enough to provide the bits you have requested");
  29. b = packed & (1 << sizeof...(Types));
  30. unpack(packed, args...);
  31. }
  32.  
  33. template<typename T, typename... Types>
  34. void unpackChecked(T packed, bool& b, Types&... args)
  35. {
  36. static_assert(std::is_integral<T>::value, "The pack type is not an integral type");
  37. if(packed >= 1 + sizeof...(Types)) {
  38. throw std::overflow_error(__PRETTY_FUNCTION__);
  39. }
  40. b = packed & (1 << sizeof...(Types));
  41. unpack(packed, args...);
  42. }
  43.  
  44. void printPackedUnpacked(int number) {
  45. bool b0, b1;
  46. unpack(number, b0, b1);
  47. std::cout << "The number you entered was:" << pack<int>(b0, b1) << "\n";
  48. }
  49.  
  50. void printPackedUnpackedChecked(int number) {
  51. bool b0, b1;
  52. unpackChecked(number, b0, b1);
  53. std::cout << "The number you entered was:" << pack<int>(b0, b1) << "\n";
  54. }
  55.  
  56. int main() {
  57. std::cout << "Enter number: ";
  58. int number;
  59. std::cin >> number;
  60. // Oops: no check if we have enough bits to represent the number
  61. printPackedUnpacked(number);
  62. //Ok, we check, but what if we decide to only use one bit and forget to
  63. //update the check itself?
  64. if(number < (1<<2))
  65. printPackedUnpacked(number);
  66. // now we don't need to update two places:
  67. try {
  68. printPackedUnpackedChecked(number);
  69. } catch(const std::overflow_error &) {
  70. std::cout << "The number you entered was to big to be processed!\n";
  71. }
  72. }
Success #stdin #stdout 0s 3480KB
stdin
9
stdout
Enter number: The number you entered was:1
The number you entered was to big to be processed!