# = bitmask.rb
#
# == Copyright (c) 2005 George Moschovitis
#
#   Ruby License
#
#   This module is free software. You may use, modify, and/or redistribute this
#   software under the same terms as Ruby.
#
#   This program is distributed in the hope that it will be useful, but WITHOUT
#   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#   FOR A PARTICULAR PURPOSE.
#
# == Authors and Contributors
#
# * Thomas Sawyer

# Author::    George Moschovitis
# Copyright:: Copyright (c) 2005 George Moschovitis
# License::   Ruby License

# = Bitmask
#
# Bitmask extends the Integer class to allow for easy manipulation
# of a number as a bit field.
#
#   0xb0100.clear_bit(3)  #=> 0
#

class Integer

  def set_bit(bit)
    mask = (1 << bit)
    self | mask
  end

  def set_bitmask(mask)
    self | mask
  end

  def clear_bit(bit)
    mask = (1 << bit)
    self & ~mask
  end

  def clear_bitmask(mask)
    self & ~mask
  end

  def test_bit(bit)
    mask = (1 << bit)
    (self & mask) != 0
  end
  alias_method :bit?, :test_bit
  alias_method :bit_set?, :test_bit

  def test_bitmask(mask)
    (self & mask) != 0
  end
  alias_method :bitmask?, :test_bitmask

end


module Kernel
  def bitmask(bit)
    1 << bit
  end
end


#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#

=begin test

  require 'test/unit'

  class TC_Integer < Test::Unit::TestCase

    def test_001
      assert_equal( 1, 0.set_bit(0) )
      assert_equal( 2, 0.set_bit(1) )
      assert_equal( 4, 0.set_bit(2) )
      assert_equal( 8, 0.set_bit(3) )
    end

    def test_002
      assert_equal( 0, 1.clear_bit(0) )
      assert_equal( 0, 2.clear_bit(1) )
      assert_equal( 0, 4.clear_bit(2) )
      assert_equal( 0, 8.clear_bit(3) )
    end

    def test_003
      a =  1
      m = bitmask(4)
      a = a.set_bitmask(m)
      assert_equal( 17, a )
      assert( a.test_bitmask(m) )
      assert( a.test_bit(4) )
      assert( a.bit_set?(4) )
      assert( ! a.test_bit(12) )
    end

  end

=end
