Class: DecimalSupport::Flags

Inherits:
Object
  • Object
show all
Defined in:
lib/decimal/support.rb

Overview

This class stores a set of flags. It can be assign a FlagValues object (using values= or passing to the constructor) so that the flags can be store in an integer (bits).

Defined Under Namespace

Classes: Error, InvalidFlagError, InvalidFlagTypeError, InvalidFlagValueError

Instance Method Summary collapse

Constructor Details

#initialize(*flags) ⇒ Flags

When a Flag object is created, the initial flags to be set can be passed, and also a FlagValues. If a FlagValues is passed an integer can be used to define the flags.

Flags.new(:flag1, :flag3, FlagValues.new(:flag1,:flag2,:flag3))
Flags.new(5, FlagValues.new(:flag1,:flag2,:flag3))


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/decimal/support.rb', line 75

def initialize(*flags)
  @values = nil
  @flags = {}

  v = 0

  flags.flatten!

  flags.each do |flag|
    case flag
      when FlagValues
        @values = flag
      when Symbol, Class
        @flags[flag] = true
      when Integer
        v |= flag
      when Flags
        @values = flag.values
        @flags = flag.to_h.dup
      else
        raise InvalidFlagTypeError, "Invalid flag type for: #{flag.inspect}"
    end
  end

  if v!=0
    raise InvalidFlagTypeError, "Integer flag values need flag bit values to be defined" if @values.nil?
    self.bits = v
  end

  if @values
    # check flags
    @flags.each_key{|flag| check flag}
  end

end

Instance Method Details

#<<(flags) ⇒ Object

Sets (makes true) one or more flags (passes as an array)



232
233
234
235
236
237
238
# File 'lib/decimal/support.rb', line 232

def << (flags)
  if flags.kind_of?(Array)
    set(*flags)
  else
    set(flags)
  end
end

#==(other) ⇒ Object



292
293
294
295
296
297
298
# File 'lib/decimal/support.rb', line 292

def ==(other)
  if @values && other.values && compatible_values?(other.values)
    bits == other.bits
  else
    to_a.map{|s| s.to_s}.sort == other.to_a.map{|s| s.to_s}.sort
  end
end

#[](flag) ⇒ Object

Retrieve the setting (true/false) of a flag



177
178
179
180
# File 'lib/decimal/support.rb', line 177

def [](flag)
  check flag
  @flags[flag]
end

#[]=(flag, value) ⇒ Object

Modifies the setting (true/false) of a flag.



183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/decimal/support.rb', line 183

def []=(flag,value)
  check flag
  case value
    when true,1
      value = true
    when false,0,nil
      value = false
    else
      raise InvalidFlagValueError, "Invalid value: #{value.inspect}"
  end
  @flags[flag] = value
  value
end

#any?Boolean

returns true if any flag is set

Returns:

  • (Boolean)


266
267
268
269
270
271
272
# File 'lib/decimal/support.rb', line 266

def any?
  if @values
    bits != 0
  else
    to_a.size>0
  end
end

#bitsObject

Retrieves the flags as a bit-vector integer. Values must have been assigned.



140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/decimal/support.rb', line 140

def bits
  if @values
    i = 0
    @flags.each do |f,v|
      bit_val = @values[f]
      i |= bit_val if v && bit_val
    end
    i
  else
    raise Error,"No flag values defined"
  end
end

#bits=(i) ⇒ Object

Sets the flags as a bit-vector integer. Values must have been assigned.



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/decimal/support.rb', line 154

def bits=(i)
  if @values
    raise Error, "Invalid bits value #{i}" if i<0 || i>@values.all_flags_value
    clear!
    @values.each do |f,v|
      @flags[f]=true if (i & v)!=0
    end
  else
    raise Error,"No flag values defined"
  end
end

#clear(*flags) ⇒ Object

Clears (makes false) one or more flags



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/decimal/support.rb', line 215

def clear(*flags)
  flags = flags.first if flags.size==1 && flags.first.instance_of?(Array)
  flags.each do |flag|
    if flag.kind_of?(Flags)
      #if @values && other.values && compatible_values(other_values)
      #  self.bits &= ~other.bits
      #else
        flags.concat other.to_a
      #end
    else
      check flag
      @flags[flag] = false
    end
  end
end

#clear!Object

Clears all flags



116
117
118
# File 'lib/decimal/support.rb', line 116

def clear!
  @flags = {}
end

#dupObject



111
112
113
# File 'lib/decimal/support.rb', line 111

def dup
  Flags.new(self)
end

#each(&blk) ⇒ Object

Iterate on each flag/setting pair.



241
242
243
244
245
246
247
248
249
# File 'lib/decimal/support.rb', line 241

def each(&blk)
  if @values
    @values.each do |f,v|
      blk.call(f,@flags[f])
    end
  else
    @flags.each(&blk)
  end
end

#each_clearObject

Iterate on each cleared flag



259
260
261
262
263
# File 'lib/decimal/support.rb', line 259

def each_clear
  each do |f,v|
    yield f if !v
  end
end

#each_setObject

Iterate on each set flag



252
253
254
255
256
# File 'lib/decimal/support.rb', line 252

def each_set
  each do |f,v|
    yield f if v
  end
end

#inspectObject



285
286
287
288
289
# File 'lib/decimal/support.rb', line 285

def inspect
  txt = "#{self.class.to_s}#{to_s}"
  txt << " (0x#{bits.to_s(16)})" if @values
  txt
end

#set(*flags) ⇒ Object

Sets (makes true) one or more flags



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/decimal/support.rb', line 198

def set(*flags)
  flags = flags.first if flags.size==1 && flags.first.instance_of?(Array)
  flags.each do |flag|
    if flag.kind_of?(Flags)
      #if @values && other.values && compatible_values(other_values)
      #  self.bits |= other.bits
      #else
        flags.concat other.to_a
      #end
    else
      check flag
      @flags[flag] = true
    end
  end
end

#set!Object

Sets all flags



121
122
123
124
125
126
127
# File 'lib/decimal/support.rb', line 121

def set!
  if @values
    self.bits = @values.all_flags_value
  else
    raise Error,"No flag values defined"
  end
end

#to_aObject

Returns the true flags as an array



275
276
277
278
279
# File 'lib/decimal/support.rb', line 275

def to_a
  a = []
  each_set{|f| a << f}
  a
end

#to_hObject

Retrieves the flags as a hash.



167
168
169
# File 'lib/decimal/support.rb', line 167

def to_h
  @flags
end

#to_iObject

Same as bits



172
173
174
# File 'lib/decimal/support.rb', line 172

def to_i
  bits
end

#to_sObject



281
282
283
# File 'lib/decimal/support.rb', line 281

def to_s
  "[#{to_a.map{|f| f.to_s.split('::').last}.join(', ')}]"
end

#valuesObject

Retrieves the flag bit values



135
136
137
# File 'lib/decimal/support.rb', line 135

def values
  @values
end

#values=(fv) ⇒ Object

Assign the flag bit values



130
131
132
# File 'lib/decimal/support.rb', line 130

def values=(fv)
  @values = fv
end