class AutoC::Record

C struct wrapper with managed fields

Attributes

fields[R]

Public Class Methods

new(type, fields, visibility: :public, profile: :blackbox, **kws) click to toggle source
Calls superclass method AutoC::Composite::new
# File lib/autoc/record.rb, line 27
def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
  super(type, visibility:, **kws)
  setup_profile(profile)
  setup_fields(fields)
end

Public Instance Methods

comparable?(= fields.values.all? { |t| t.comparable? }) click to toggle source
# File lib/autoc/record.rb, line 22
  def comparable? = fields.values.all? { |t| t.comparable? }
  def copyable? = fields.values.all? { |t| t.copyable? }
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  end

configure() click to toggle source
Calls superclass method AutoC::Composite#configure
# File lib/autoc/record.rb, line 121
def configure
  super
  ### set
    params = []
    docs = []
    args = { target: lvalue }
    fields.each do |name, type|
      formal = "#{name}".to_sym
      value = type.const_rvalue
      params << [name, Parameter.new(value, formal)]
      args[formal] = value
      docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
    end
    method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
      _code = 'assert(target);'
      params.each do |field, parameter|
        _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
      end
      code _code
      header %{
        @brief Initialize record

        @param[in] target record to create

        This function initializes new record's fields with copies of respective arguments.

        Previous contents of `*target` is overwritten.

        @since 2.0
      }
    end
  ### default_create
    _code = 'assert(target);'
    fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
    default_create.configure { code _code }
  ### destroy
    _code = 'assert(target);'
    fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
    destroy.configure { code _code }
  ### copy
    _code = 'assert(target); assert(source);'
    fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
    copy.configure { code _code }
  ### equal
    _code = 'assert(left); assert(right);'
    _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
    equal.configure { code _code }
  ### hash_code
    _code = %{
      #{hasher.to_s} hash;
      size_t result;
      assert(target);
      #{hasher.create(:hash)};
    }
    fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
    _code += %{
      result = #{hasher.result(:hash)};
      #{hasher.destroy(hash)};
      return result;
    }
    hash_code.configure { code _code }
  ###
  unless @omit_accessors
    fields.each do |name, type|
      method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
        code %{
          assert(target);
          return &target->#{name};
        }
      header %{
        @brief Get a view of the field #{name}

        @param[in] target record to query
        @return a view of the value of type #{type} contained in field #{name}

        This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

        @since 2.0
      }
      end
      if type.copyable?
        method(type, "get_#{name}",  { target: const_rvalue } ).configure do
          code %{
            #{type} result;
            assert(target);
            #{type.copy.(:result, "target->#{name}")};
            return result;
          }
        header %{
          @brief Get a copy of the value of field #{name}

          @param[in] target record to query
          @return a copy of the value of type #{type} contained in field #{name}

          This function is used to get a copy the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
          code %{
            assert(target);
            #{type.destroy.("target->#{name}") if type.destructible?};
            #{type.copy.("target->#{name}", value)};
          }
        header %{
          @brief Set value of field #{name}

          @param[in] target record to modify
          @param[in] value value to initalize field #{name} with

          This function sets the field #{name} to contain a copy of specified value.

          Previous field's contents is destroyed the respective destructor.

          @since 2.0
        }
        end
      end
    end
  end
end
copyable?(= fields.values.all? { |t| t.copyable? }) click to toggle source
# File lib/autoc/record.rb, line 23
  def copyable? = fields.values.all? { |t| t.copyable? }
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  end

end 
custom_constructible?(= fields.values.all? { |t| t.copyable? }) click to toggle source
# File lib/autoc/record.rb, line 20
  def custom_constructible? = fields.values.all? { |t| t.copyable? }
  def destructible? = fields.values.any? { |t| t.destructible? }
  def comparable? = fields.values.all? { |t| t.comparable? }
  def copyable? = fields.values.all? { |t| t.copyable? }
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  
default_constructible?(= fields.values.all? { |t| t.default_constructible? }) click to toggle source
# File lib/autoc/record.rb, line 19
  def default_constructible? = fields.values.all? { |t| t.default_constructible? }
  def custom_constructible? = fields.values.all? { |t| t.copyable? }
  def destructible? = fields.values.any? { |t| t.destructible? }
  def comparable? = fields.values.all? { |t| t.comparable? }
  def copyable? = fields.values.all? { |t| t.copyable? }
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
destructible?(= fields.values.any? { |t| t.destructible? }) click to toggle source
# File lib/autoc/record.rb, line 21
  def destructible? = fields.values.any? { |t| t.destructible? }
  def comparable? = fields.values.all? { |t| t.comparable? }
  def copyable? = fields.values.all? { |t| t.copyable? }
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  end
field_declaration(type, name) click to toggle source

@private

# File lib/autoc/record.rb, line 115
def field_declaration(type, name)
  s = "#{type} #{field_variable(name)};"
  s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
  s
end
field_variable(opt) click to toggle source

@private

# File lib/autoc/record.rb, line 105
def field_variable(opt)
  if opt.is_a?(::Hash)
    obj, name = opt.first
    "#{obj}->#{name}"
  else
    opt
  end
end
hashable?(= fields.values.all? { |t| t.hashable? }) click to toggle source
# File lib/autoc/record.rb, line 24
  def hashable? = fields.values.all? { |t| t.hashable? }
  def orderable? = false

  def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
    super(type, visibility:, **kws)
    setup_profile(profile)
    setup_fields(fields)
  end

  def render_interface(stream)
    if public?
      stream << %{
        /**
          #{defgroup}

          @brief Value type wrapper of the C struct

          @since 2.0
        */
      }
      if @opaque
        stream << %{
          /**
            #{ingroup}

            @brief Opaque struct holding state of the record

            @since 2.0
          */
        }
      else
        stream << %{
          /**
            #{ingroup}

            @brief Open struct holding state of the record

            The struct's fields are directly acessible.
            However, care must be taken when modifying the struct's contents directly
            as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

            For the safety reasons these fields should be generally treated read-only.

            @since 2.0
          */
        }
      end
    else
      stream << PRIVATE
    end
    stream << 'typedef struct {'
      fields.each { |name, type| stream << field_declaration(type, name) }
    stream << "} #{signature};"
  end

  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  end

end # Record

orderable?(= false) click to toggle source
# File lib/autoc/record.rb, line 25
    def orderable? = false
  
    def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
      super(type, visibility:, **kws)
      setup_profile(profile)
      setup_fields(fields)
    end

    def render_interface(stream)
      if public?
        stream << %{
          /**
            #{defgroup}

            @brief Value type wrapper of the C struct

            @since 2.0
          */
        }
        if @opaque
          stream << %{
            /**
              #{ingroup}

              @brief Opaque struct holding state of the record

              @since 2.0
            */
          }
        else
          stream << %{
            /**
              #{ingroup}

              @brief Open struct holding state of the record

              The struct's fields are directly acessible.
              However, care must be taken when modifying the struct's contents directly
              as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

              For the safety reasons these fields should be generally treated read-only.

              @since 2.0
            */
          }
        end
      else
        stream << PRIVATE
      end
      stream << 'typedef struct {'
        fields.each { |name, type| stream << field_declaration(type, name) }
      stream << "} #{signature};"
    end

    def type_tag = "#{signature}<#{fields.values.join(',')}>"

  private

    # @private
    def setup_fields(fields)
      @fields = fields.transform_values { |type| type.to_type }
      self.fields.each_value { |type| dependencies << type }
    end

    # @private
    def setup_profile(profile)
      case profile
      when :blackbox
        #@inline_methods = false
        @omit_accessors = false
        @opaque = true
      when :glassbox
        #@inline_methods = true
        @omit_accessors = true
        @opaque = false
      else raise "unsupported profile #{profile}"
      end
    end

    # @private
    def field_variable(opt)
      if opt.is_a?(::Hash)
        obj, name = opt.first
        "#{obj}->#{name}"
      else
        opt
      end
    end

    # @private
    def field_declaration(type, name)
      s = "#{type} #{field_variable(name)};"
      s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
      s
    end

    def configure
      super
      ### set
        params = []
        docs = []
        args = { target: lvalue }
        fields.each do |name, type|
          formal = "#{name}".to_sym
          value = type.const_rvalue
          params << [name, Parameter.new(value, formal)]
          args[formal] = value
          docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
        end
        method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
          _code = 'assert(target);'
          params.each do |field, parameter|
            _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
          end
          code _code
          header %{
            @brief Initialize record

            @param[in] target record to create

            This function initializes new record's fields with copies of respective arguments.

            Previous contents of `*target` is overwritten.

            @since 2.0
          }
        end
      ### default_create
        _code = 'assert(target);'
        fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
        default_create.configure { code _code }
      ### destroy
        _code = 'assert(target);'
        fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
        destroy.configure { code _code }
      ### copy
        _code = 'assert(target); assert(source);'
        fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
        copy.configure { code _code }
      ### equal
        _code = 'assert(left); assert(right);'
        _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
        equal.configure { code _code }
      ### hash_code
        _code = %{
          #{hasher.to_s} hash;
          size_t result;
          assert(target);
          #{hasher.create(:hash)};
        }
        fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
        _code += %{
          result = #{hasher.result(:hash)};
          #{hasher.destroy(hash)};
          return result;
        }
        hash_code.configure { code _code }
      ###
      unless @omit_accessors
        fields.each do |name, type|
          method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
            code %{
              assert(target);
              return &target->#{name};
            }
          header %{
            @brief Get a view of the field #{name}

            @param[in] target record to query
            @return a view of the value of type #{type} contained in field #{name}

            This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          if type.copyable?
            method(type, "get_#{name}",  { target: const_rvalue } ).configure do
              code %{
                #{type} result;
                assert(target);
                #{type.copy.(:result, "target->#{name}")};
                return result;
              }
            header %{
              @brief Get a copy of the value of field #{name}

              @param[in] target record to query
              @return a copy of the value of type #{type} contained in field #{name}

              This function is used to get a copy the value in field #{name} contained in `target`.

              @since 2.0
            }
            end
            method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
              code %{
                assert(target);
                #{type.destroy.("target->#{name}") if type.destructible?};
                #{type.copy.("target->#{name}", value)};
              }
            header %{
              @brief Set value of field #{name}

              @param[in] target record to modify
              @param[in] value value to initalize field #{name} with

              This function sets the field #{name} to contain a copy of specified value.

              Previous field's contents is destroyed the respective destructor.

              @since 2.0
            }
            end
          end
        end
      end
    end

  end # Record


end
render_interface(stream) click to toggle source
# File lib/autoc/record.rb, line 33
def render_interface(stream)
  if public?
    stream << %{
      /**
        #{defgroup}

        @brief Value type wrapper of the C struct

        @since 2.0
      */
    }
    if @opaque
      stream << %{
        /**
          #{ingroup}

          @brief Opaque struct holding state of the record

          @since 2.0
        */
      }
    else
      stream << %{
        /**
          #{ingroup}

          @brief Open struct holding state of the record

          The struct's fields are directly acessible.
          However, care must be taken when modifying the struct's contents directly
          as it may break the contract(s) of certain (namely, hash- and tree-based) containers.

          For the safety reasons these fields should be generally treated read-only.

          @since 2.0
        */
      }
    end
  else
    stream << PRIVATE
  end
  stream << 'typedef struct {'
    fields.each { |name, type| stream << field_declaration(type, name) }
  stream << "} #{signature};"
end
setup_fields(fields) click to toggle source

@private

# File lib/autoc/record.rb, line 84
def setup_fields(fields)
  @fields = fields.transform_values { |type| type.to_type }
  self.fields.each_value { |type| dependencies << type }
end
setup_profile(profile) click to toggle source

@private

# File lib/autoc/record.rb, line 90
def setup_profile(profile)
  case profile
  when :blackbox
    #@inline_methods = false
    @omit_accessors = false
    @opaque = true
  when :glassbox
    #@inline_methods = true
    @omit_accessors = true
    @opaque = false
  else raise "unsupported profile #{profile}"
  end
end
type_tag(= " click to toggle source
# File lib/autoc/record.rb, line 79
  def type_tag = "#{signature}<#{fields.values.join(',')}>"

private

  # @private
  def setup_fields(fields)
    @fields = fields.transform_values { |type| type.to_type }
    self.fields.each_value { |type| dependencies << type }
  end

  # @private
  def setup_profile(profile)
    case profile
    when :blackbox
      #@inline_methods = false
      @omit_accessors = false
      @opaque = true
    when :glassbox
      #@inline_methods = true
      @omit_accessors = true
      @opaque = false
    else raise "unsupported profile #{profile}"
    end
  end

  # @private
  def field_variable(opt)
    if opt.is_a?(::Hash)
      obj, name = opt.first
      "#{obj}->#{name}"
    else
      opt
    end
  end

  # @private
  def field_declaration(type, name)
    s = "#{type} #{field_variable(name)};"
    s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
    s
  end

  def configure
    super
    ### set
      params = []
      docs = []
      args = { target: lvalue }
      fields.each do |name, type|
        formal = "#{name}".to_sym
        value = type.const_rvalue
        params << [name, Parameter.new(value, formal)]
        args[formal] = value
        docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
      end
      method(:void, :create_set, args, instance: :custom_create, constraint:-> { custom_constructible? }).configure do
        _code = 'assert(target);'
        params.each do |field, parameter|
          _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
        end
        code _code
        header %{
          @brief Initialize record

          @param[in] target record to create

          This function initializes new record's fields with copies of respective arguments.

          Previous contents of `*target` is overwritten.

          @since 2.0
        }
      end
    ### default_create
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
      default_create.configure { code _code }
    ### destroy
      _code = 'assert(target);'
      fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
      destroy.configure { code _code }
    ### copy
      _code = 'assert(target); assert(source);'
      fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
      copy.configure { code _code }
    ### equal
      _code = 'assert(left); assert(right);'
      _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
      equal.configure { code _code }
    ### hash_code
      _code = %{
        #{hasher.to_s} hash;
        size_t result;
        assert(target);
        #{hasher.create(:hash)};
      }
      fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
      _code += %{
        result = #{hasher.result(:hash)};
        #{hasher.destroy(hash)};
        return result;
      }
      hash_code.configure { code _code }
    ###
    unless @omit_accessors
      fields.each do |name, type|
        method(type.const_lvalue, "view_#{name}",  { target: const_lvalue }, inline: true ).configure do
          code %{
            assert(target);
            return &target->#{name};
          }
        header %{
          @brief Get a view of the field #{name}

          @param[in] target record to query
          @return a view of the value of type #{type} contained in field #{name}

          This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.

          @since 2.0
        }
        end
        if type.copyable?
          method(type, "get_#{name}",  { target: const_rvalue } ).configure do
            code %{
              #{type} result;
              assert(target);
              #{type.copy.(:result, "target->#{name}")};
              return result;
            }
          header %{
            @brief Get a copy of the value of field #{name}

            @param[in] target record to query
            @return a copy of the value of type #{type} contained in field #{name}

            This function is used to get a copy the value in field #{name} contained in `target`.

            @since 2.0
          }
          end
          method(:void, "set_#{name}",  { target: rvalue, value: type.const_rvalue } ).configure do
            code %{
              assert(target);
              #{type.destroy.("target->#{name}") if type.destructible?};
              #{type.copy.("target->#{name}", value)};
            }
          header %{
            @brief Set value of field #{name}

            @param[in] target record to modify
            @param[in] value value to initalize field #{name} with

            This function sets the field #{name} to contain a copy of specified value.

            Previous field's contents is destroyed the respective destructor.

            @since 2.0
          }
          end
        end
      end
    end
  end

end