Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bitset Initialization

86 views
Skip to first unread message

MikeCopeland

unread,
Nov 29, 2015, 3:27:32 PM11/29/15
to
Is there a way to initialize a non-contiguous number of bits in a
std::bitset (other than with a string of 0 or 1 bits with those desired
bits as 1)? That is, I have a declration of:
std::bitset<100> myBits;
and I want to set the following bits:
7, 9, 43, 47, 51-59, 66, 67
I can, of course, construct a string constant of these bits, but it's
tedious to code and completely lacking in good documentation...
Is there an easy way to do so in source code? TIA


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

BartC

unread,
Nov 29, 2015, 4:19:59 PM11/29/15
to
On 29/11/2015 20:27, MikeCopeland wrote:
> Is there a way to initialize a non-contiguous number of bits in a
> std::bitset (other than with a string of 0 or 1 bits with those desired
> bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
> and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but it's
> tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA

I just saw this post by chance and know nothing of the capabilities of C++.

But your requirement reminds me of the Pascal way to do the same:

var myBits: set of 1..100;

myBits := [7, 9, 43, 47, 51..59, 66, 67];

So exactly as you've denoted except for using .. for the range (I assume
you don't mean -8).

This can serve as a target anyway.

--
Bartc

Paavo Helde

unread,
Nov 29, 2015, 5:07:43 PM11/29/15
to
MikeCopeland <mrc...@cox.net> wrote in news:MPG.30c50d893dd76c039896b7
@news.eternal-september.org:

> Is there a way to initialize a non-contiguous number of bits in a
> std::bitset (other than with a string of 0 or 1 bits with those desired
> bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
> and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but
it's
> tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA

Not quite one line, but close (C++11):

#include <iostream>
#include <bitset>

int main() {
std::bitset<100> mybitset;
for (auto bit:
{7, 9, 43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67})
{
mybitset.set(bit);
}

std::cout << mybitset.to_string() << "\n";
}

or more fancy & verbose:

#include <iostream>
#include <numeric>
#include <bitset>
#include <iterator>

int main() {
using b100 = std::bitset<100>;

const int bits[] =
{7, 9, 43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67};

b100 mybitset =
std::accumulate(std::begin(bits), std::end(bits), b100(),
[](b100 bset, int bit) {bset.set(bit); return bset; });

std::cout << mybitset.to_string() << "\n";
}

Geoff

unread,
Nov 29, 2015, 6:31:15 PM11/29/15
to
On Sun, 29 Nov 2015 13:27:11 -0700, MikeCopeland <mrc...@cox.net>
wrote:

> Is there a way to initialize a non-contiguous number of bits in a
>std::bitset (other than with a string of 0 or 1 bits with those desired
>bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
>and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but it's
>tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA
>
>

I don't see a way to express the range 51-59 but here's my solution:

#include <iostream>
#include <bitset>

int main (void)
{
std::bitset<100> myBits;
const int mySets[] =
{7, 9, 43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67};

for (int i = 0; i < sizeof(mySets)/sizeof(int); i++)
myBits.set(mySets[i]);

std::cout << "Bits ";
for (size_t i = 0; i < myBits.size(); i++) {
if (myBits.test(i)) {
std::cout << i << " ";
}
}
std::cout << "are set." << std::endl;
}

Alf P. Steinbach

unread,
Nov 29, 2015, 10:38:19 PM11/29/15
to
On 11/29/2015 9:27 PM, MikeCopeland wrote:
> Is there a way to initialize a non-contiguous number of bits in a
> std::bitset (other than with a string of 0 or 1 bits with those desired
> bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
> and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but it's
> tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA

The answers so far have just presented short, easy to grasp code.

But a challenge to simplify one little aspect of notation requires lots
more code, to hone that little aspect down to the very simplest! Like

my::Bits<100> const bits = { 7, 9, 43, 47, Range( 51, 59 ), 66, 67 };

In the following I have however refrained from adding the most obvious
things like standard typedefs for iterators, or a formally correct
operator++(int); I leave those details to the reader!

<code>
#include <bitset>
#include <functional> // std::equal_to, std::less
#include <initializer_list>
#include <iostream>
#include <stddef.h> // ptrdiff_t
#include <utility> // std::move

namespace my {
using std::bitset;
using std::equal_to;
using std::initializer_list;
using std::less;
using std::move;

using Size = ptrdiff_t;

template< class Type >
auto n_items( Type const& o ) -> Size { return o.size(); }

template< class Type >
auto stdcmp( Type&& a, Type&& b )
-> int
{
using Eq = equal_to<Type>;
using Lt = less<Type>;
return (Eq()( a, b )? 0 : Lt()( a, b )? -1 : +1);
}

template< class State >
class Forward_iterator
{
private:
State state_;

public:
friend
auto operator==( Forward_iterator const& a, Forward_iterator
const& b )
-> bool
{ return (compare( a.state_, b.state_ ) == 0); }

friend
auto operator!=( Forward_iterator const& a, Forward_iterator
const& b )
-> bool
{ return (compare( a.state_, b.state_ ) != 0); }

auto operator++()
-> Forward_iterator&
{ state_.advance(); return *this; }

void operator++( int )
{
//Forward_iterator result = *this;
state_.advance();
//return result;
}

auto operator*() const
-> decltype( state_.referent() )
{ return state_.referent(); }

Forward_iterator( State state ): state_( move( state ) ) {}
};

template< class Type = int >
class Int_range
{
private:
Type first_;
Type last_;

class Iterstate
{
friend class Int_range<Type>;
private:
Int_range const* p_range_;
Type current_;

Iterstate( Int_range const& range, Type const where )
: p_range_( &range ), current_( where )
{}

public:
friend
auto compare( Iterstate const& a, Iterstate const& b )
-> int
{
if( int const r = stdcmp( a.p_range_, b.p_range_ ) ) {
return r; };
return stdcmp( a.current_, b.current_ );
}

void advance() { ++current_; }
auto referent() const -> Type { return current_; }
};

public:
using Iterator = Forward_iterator<Iterstate>;

auto begin() const
-> Iterator
{ return Iterator( Iterstate( *this, first_ ) ); }

auto end() const
-> Iterator
{ return Iterator( Iterstate( *this, last_ + 1 ) ); }

Int_range( Type const value )
: first_( value ), last_( value )
{}

Int_range( Type const a, Type const b )
: first_( a ), last_( b )
{}
};

template< Size n >
class Bits
: public std::bitset< n >
{
public:
Bits( initializer_list<Int_range<>> const& one_bits )
{
for( Int_range<> const& r : one_bits )
{
for( int const i : r )
{
this->set( i );
}
}
}
};
} // namespace my

auto main() -> int
{
using Range = my::Int_range<>;
my::Bits<100> const bits = { 7, 9, 43, 47, Range( 51, 59 ), 66, 67 };

std::cout << "Bits ";
for ( int i = 0; i < n_items( bits ); i++)
{
if( bits.test(i) )
{
std::cout << i << ' ';
}
}
std::cout << "are set." << std::endl;
}
</code>

Cheers, & hth.,

- Alf


Öö Tiib

unread,
Nov 30, 2015, 1:26:02 AM11/30/15
to
On Sunday, 29 November 2015 22:27:32 UTC+2, MikeCopeland wrote:
> Is there a way to initialize a non-contiguous number of bits in a
> std::bitset (other than with a string of 0 or 1 bits with those desired
> bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
> and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but it's
> tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA

To set 15 concrete bits you can just use 'set':

#include <iostream>
#include <bitset>

int main()
{
std::bitset<100> myBits;
myBits.set( 7).set( 9).set(43).set(47).set(51)
.set(52).set(53).set(54).set(55).set(56)
.set(57).set(58).set(59).set(66).set(67);

std::cout << myBits << '\n';
}

Magic numbers make it to look like binary dump, better name your bits.

Paavo Helde

unread,
Nov 30, 2015, 3:31:29 AM11/30/15
to
BartC <b...@freeuk.com> wrote in news:n3fq0t$v2$1...@dont-email.me:

> On 29/11/2015 20:27, MikeCopeland wrote:
>> Is there a way to initialize a non-contiguous number of bits in a
>> std::bitset (other than with a string of 0 or 1 bits with those
>> desired bits as 1)? That is, I have a declration of:
>> std::bitset<100> myBits;
>> and I want to set the following bits:
>> 7, 9, 43, 47, 51-59, 66, 67
>> I can, of course, construct a string constant of these bits, but
>> it's
>> tedious to code and completely lacking in good documentation...
>> Is there an easy way to do so in source code? TIA
>
> I just saw this post by chance and know nothing of the capabilities of
> C++.
>
> But your requirement reminds me of the Pascal way to do the same:
>
> var myBits: set of 1..100;
>
> myBits := [7, 9, 43, 47, 51..59, 66, 67];
>

In C++ there are two different containers for holding such things,
std::set and std::bitset. I guess the Pascal sets are internally
implemented similarly to C++ std::set. Coincidentally, initializing a
std::set would indeed be one line in C++:

std::set<int> myBits {7, 9, 43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59,
66, 67};

Alas, integer type range restriction is not present here. One could use a
custom class (e.g. boost::constrained_value) instead of int here, but
this is not in standard.

std::bitset is a different beast which encapsulates an array of bits.
Coincidentally, it suits better for emulating Pascal subrange type 'set
of 0..N', for small values of N. Alas, it is lacking a convenience
constructor taking a list of bits, I guess this might be just an
oversight.

Cheers
Paavo

Juha Nieminen

unread,
Nov 30, 2015, 4:24:51 AM11/30/15
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> using std::bitset;
> using std::equal_to;
> using std::initializer_list;
> using std::less;
> using std::move;

Why?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

K. Frank

unread,
Nov 30, 2015, 9:40:12 AM11/30/15
to
Hi Juha (and Alf)!

On Monday, November 30, 2015 at 4:24:51 AM UTC-5, Juha Nieminen wrote:
> Alf P. Steinbach <alf.rhymes...@gxx.com> wrote:
> > using std::bitset;
> > using std::equal_to;
> > using std::initializer_list;
> > using std::less;
> > using std::move;
>
> Why?

Why?

Because this is a c++ newsgroup where people explore
ideas with like-minded (or sometimes unlike-minded)
members of the community. It's a good place to try
things out that might be interesting but not fully
baked, and might not have a place in production code.

Personally, I welcome Alf's posts. Some of them I
find to be gratuitous overkill, but others I find
to be informative and thought-provoking, even if I
wouldn't use them in "real" code.

It's good to experiment.

And in fairness, Alf did begin his post with:

> The answers so far have just presented short, easy
> to grasp code.

> But a challenge to simplify one little aspect of
> notation requires lots more code, to hone that little
> aspect down to the very simplest!

which I take to be Alf-speak for "others have already
posted the practical solution, but let's go ahead and
have a little fun here ..."

Or, in short, why not?


Happy Hacking!


K. Frank

David Brown

unread,
Nov 30, 2015, 9:53:13 AM11/30/15
to
On 30/11/15 10:24, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>> using std::bitset;
>> using std::equal_to;
>> using std::initializer_list;
>> using std::less;
>> using std::move;
>
> Why?
>

My guess is that Alf wants to simplify the code that uses these common
identifiers, but does not want a global "using std" to fill up his
namespace.

It is also possible that he uses a common #include file in his
programming that lists a number of these "using" clauses, but for the
example here he has copied them in directly. Perhaps in his normal code
he simply writes #include "using_std.h" to bring in a few dozen common
identifiers.


Öö Tiib

unread,
Nov 30, 2015, 11:18:35 AM11/30/15
to
On Monday, 30 November 2015 16:53:13 UTC+2, David Brown wrote:
> On 30/11/15 10:24, Juha Nieminen wrote:
> > Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> >> using std::bitset;
> >> using std::equal_to;
> >> using std::initializer_list;
> >> using std::less;
> >> using std::move;
> >
> > Why?
> >
>
> My guess is that Alf wants to simplify the code that uses these common
> identifiers, but does not want a global "using std" to fill up his
> namespace.

You meant 'using namespace std'.

>
> It is also possible that he uses a common #include file in his
> programming that lists a number of these "using" clauses, but for the
> example here he has copied them in directly. Perhaps in his normal code
> he simply writes #include "using_std.h" to bring in a few dozen common
> identifiers.

That is unlikely. It was still about declaring names in namespace 'my'.

The row of using declarations (that replace less flexible 'typedef' of
C++03) is like "terms and abbreviations" at start of document.

IOW that:

namespace my {
using std::bitset;
}

It means that 'bitset' in context of 'my' means 'std::bitset'.
Or that:

namespace my {
template<std::size_t N>
using Flags = std::bitset<N>;
}

It means that 'Flags' in namespace 'my' means 'std::bitset'.

Such aliasing perhaps gives diminishing returns on case of 'std::bitset'
but can make usage of types with long names (like
std::chrono::high_resolution_clock) or very flexibly configurable
templates (like 'boost::multi_index_container' or
'boost::adjacency_matrix') notably more readable.

However once we use aliasing to some names from other scopes then it
can be considered cleaner and more uniform to alias every "foreign"
name used.

Juha Nieminen

unread,
Nov 30, 2015, 1:57:08 PM11/30/15
to
K. Frank <kfran...@gmail.com> wrote:
> On Monday, November 30, 2015 at 4:24:51 AM UTC-5, Juha Nieminen wrote:
>> Alf P. Steinbach <alf.rhymes...@gxx.com> wrote:
>> > using std::bitset;
>> > using std::equal_to;
>> > using std::initializer_list;
>> > using std::less;
>> > using std::move;
>>
>> Why?
>
> Why?
>
> Because this is a c++ newsgroup where people explore
> ideas with like-minded (or sometimes unlike-minded)
> members of the community. It's a good place to try
> things out that might be interesting but not fully
> baked, and might not have a place in production code.

My objection was not to his program or his contribution.
My objection was to his needless abuse of 'using'.

Luca Risolia

unread,
Dec 1, 2015, 10:33:13 AM12/1/15
to
On 29/11/2015 21:27, MikeCopeland wrote:
> Is there a way to initialize a non-contiguous number of bits in a
> std::bitset (other than with a string of 0 or 1 bits with those desired
> bits as 1)? That is, I have a declration of:
> std::bitset<100> myBits;
> and I want to set the following bits:
> 7, 9, 43, 47, 51-59, 66, 67
> I can, of course, construct a string constant of these bits, but it's
> tedious to code and completely lacking in good documentation...
> Is there an easy way to do so in source code? TIA

consider an helper function taking a variable number of bit positions,
for example:

template<std::size_t N, typename...Pos>
void setbits(std::bitset<N>& bs, Pos... pos) noexcept {
(void)std::initializer_list<int>{((void) bs.set(pos), 0)...};
}

and use it this way:

std::bitset<100> myBits;
setbits(myBits, 7,9,43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67);

or, if you prefer:

template<std::size_t N>
void setbits(std::bitset<N>& bs, std::initializer_list<std::size_t>) {}

asetof...@gmail.com

unread,
Dec 6, 2015, 5:40:43 AM12/6/15
to
setbit(&n,7,9,43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67);

asetof...@gmail.com

unread,
Dec 6, 2015, 5:50:25 AM12/6/15
to
On Sunday, December 6, 2015 at 11:40:43 AM UTC+1, asetof...@gmail.com wrote:
> setbit(&n,7,9,43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67);

✔(&n,7,9,43, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 66, 67)

asetof...@gmail.com

unread,
Dec 6, 2015, 5:53:40 AM12/6/15
to
a=✔(&n,7,9,43,47,51..59,66,67)

asetof...@gmail.com

unread,
Dec 6, 2015, 6:53:42 AM12/6/15
to
On Sunday, December 6, 2015 at 11:53:40 AM UTC+1, asetof...@gmail.com wrote:
> a=✔(&n,7,9,43,47,51..59,66,67)

a=✔(&n,7,9,43,47,51…59,66,67)

Öö Tiib

unread,
Dec 6, 2015, 7:07:56 AM12/6/15
to
Can't be that you have nothing more fruitful to do but to post such
questionable pieces of unicode art?

asetof...@gmail.com

unread,
Dec 6, 2015, 8:03:18 AM12/6/15
to
On Sunday, December 6, 2015 at 11:53:40 AM UTC+1, asetof...@gmail.com wrote:
> a=✔(&n,7,9,43,47,51..59,66,67)
Bits n
&n✔[7,9,43,47,51..59,66,67]
Set n as bit vector
where bit 7,9,43,47,51..59,66,67
are 1
The bit remain
are 0

asetof...@gmail.com

unread,
Dec 6, 2015, 8:12:39 AM12/6/15
to
Perhaps better something as:
Bits n
n✔=[7,9,43,47,51.59,66,67]

asetof...@gmail.com

unread,
Dec 6, 2015, 8:20:14 AM12/6/15
to
Possibly would be better just this
Bit n|n=[7,9,43,47,51.59,66,67]
0 new messages