1

i know we can convert a string to bitset by following way:

std::bitset<8> my_bitset(std::string("00011100");

but what if the string is being taken as input by user or from some file and the size of string may vary.

In above example we knew the size of string is 8, so we initialized the bitset size by 8.

I tried passing the size of string but got compilation error.

  • 1
    The short answer: you can't use bitset. The bitset's size must be specified at compile time. End of story. You'll have to use some other container. – Sam Varshavchik Sep 05 '16 at 15:01
  • if you have some small range of possible bitset lengths, it is possible, though will require cognitive leap to understand what the code does. – Incomputable Sep 05 '16 at 15:02
  • See variable size bitset question [here](http://stackoverflow.com/questions/14433626/variable-size-bitset) – wally Sep 05 '16 at 15:05
  • @flatmouse it is suggesting me to go for ` vector ` – Rajan Kumar Sep 05 '16 at 15:09
  • 1
    Yes, it does suggest that. `std::vector` [might be better](http://en.cppreference.com/w/cpp/container/vector_bool) than something you come with yourself to store bits. – wally Sep 05 '16 at 15:22
  • You might want to try [boost::dynamic_bitset](http://www.boost.org/doc/libs/1_57_0/boost/dynamic_bitset/dynamic_bitset.hpp) – for_stack Sep 05 '16 at 15:48

1 Answers1

0

This question could be rephrased more generally as, "how do I execute compile-time generated code using runtime attributes?"

The basic answer is to build a compile-time array of pointers to the templatised functions that do the work, and then index into that array.

#include <bitset>
#include <cstdint>
#include <array>
#include <utility>

// define the parameters of supported lengths
struct traits
{
  static const std::size_t lowest = 1;
  static const std::size_t highest = 64;
  static const std::size_t extent = (highest - lowest) + 1;
};

//
// use a bitset of some length to decode the string
//
template<std::size_t Bits>
unsigned long long decode_impl(std::string const& s)
{
  std::bitset<Bits> bs(s);
  return bs.to_ullong();
}

//
// build an array of pointers to the decode functions, one for each Is
//
template<std::size_t...Is>
constexpr std::array<unsigned long long (*)(std::string const&), traits::extent>
decoders(std::index_sequence<Is...>)
{
  return {{
    &decode_impl<Is + traits::lowest>...
  }};
}

//
// build all pointers
//
std::array<unsigned long long (*)(std::string const&), traits::extent>
constexpr decoders()
{
  return decoders(std::make_index_sequence<traits::extent>());
}

//
// use runtime attributes to switch into compile-time constructs
//
unsigned long long decode(std::string const& s)
{
  static constexpr auto my_decoders = decoders();

  auto sz = std::max(s.size(), traits::lowest);
  if (sz > traits::highest)
    throw std::logic_error("unsupported length");
  return my_decoders[sz - traits::lowest](s);

}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142