module Concurrent::Synchronization::AbstractStruct

def self.define_struct_class(parent, base, name, members, &block)

@!visibility private
def self.define_struct_class(parent, base, name, members, &block)
  clazz = Class.new(base || Object) do
    include parent
    self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze)
    def ns_initialize(*values)
      raise ArgumentError.new('struct size differs') if values.length > length
      @values = values.fill(nil, values.length..length-1)
    end
  end
  unless name.nil?
    begin
      parent.send :remove_const, name if parent.const_defined?(name, false)
      parent.const_set(name, clazz)
      clazz
    rescue NameError
      raise NameError.new("identifier #{name} needs to be constant")
    end
  end
  members.each_with_index do |member, index|
    clazz.send :remove_method, member if clazz.instance_methods(false).include? member
    clazz.send(:define_method, member) do
      @values[index]
    end
  end
  clazz.class_exec(&block) unless block.nil?
  clazz.singleton_class.send :alias_method, :[], :new
  clazz
end