<commit_before>use crate::gen::block::Block;
use crate::gen::ifndef;
use crate::gen::out::{Content, OutFile};

#[derive(Default, PartialEq)]
pub struct Builtins<'a> {
    pub panic: bool,
    pub rust_string: bool,
    pub rust_str: bool,
    pub rust_slice: bool,
    pub rust_box: bool,
    pub rust_vec: bool,
    pub rust_fn: bool,
    pub rust_isize: bool,
    pub opaque: bool,
    pub layout: bool,
    pub unsafe_bitcopy: bool,
    pub rust_error: bool,
    pub manually_drop: bool,
    pub maybe_uninit: bool,
    pub trycatch: bool,
    pub ptr_len: bool,
    pub repr_fat: bool,
    pub rust_str_new_unchecked: bool,
    pub rust_str_repr: bool,
    pub rust_slice_new: bool,
    pub rust_slice_repr: bool,
    pub exception: bool,
    pub relocatable: bool,
    pub friend_impl: bool,
    pub is_complete: bool,
    pub deleter_if: bool,
    pub content: Content<'a>,
}

impl<'a> Builtins<'a> {
    pub fn new() -> Self {
        Builtins::default()
    }
}

pub(super) fn write(out: &mut OutFile) {
    if out.builtin == Default::default() {
        return;
    }

    let include = &mut out.include;
    let builtin = &mut out.builtin;
    let out = &mut builtin.content;

    if builtin.rust_string {
        include.array = true;
        include.cstdint = true;
        include.string = true;
    }

    if builtin.rust_str {
        include.array = true;
        include.cstdint = true;
        include.string = true;
        builtin.friend_impl = true;
    }

    if builtin.rust_vec {
        include.algorithm = true;
        include.array = true;
        include.cassert = true;
        include.cstddef = true;
        include.cstdint = true;
        include.initializer_list = true;
        include.iterator = true;
        include.new = true;
        include.type_traits = true;
        include.utility = true;
        builtin.panic = true;
        builtin.rust_slice = true;
        builtin.unsafe_bitcopy = true;
    }

    if builtin.rust_slice {
        include.array = true;
        include.cassert = true;
        include.cstddef = true;
        include.cstdint = true;
        include.iterator = true;
        include.type_traits = true;
        builtin.friend_impl = true;
        builtin.layout = true;
        builtin.panic = true;
    }

    if builtin.rust_box {
        include.new = true;
        include.type_traits = true;
        include.utility = true;
    }

    if builtin.rust_fn {
        include.utility = true;
    }

    if builtin.rust_error {
        include.exception = true;
        builtin.friend_impl = true;
    }

    if builtin.rust_isize {
        include.basetsd = true;
        include.sys_types = true;
    }

    if builtin.relocatable {
        include.type_traits = true;
    }

    if builtin.layout {
        include.type_traits = true;
        include.cstddef = true;
        builtin.is_complete = true;
    }

    if builtin.is_complete {
        include.cstddef = true;
        include.type_traits = true;
    }

    out.begin_block(Block::Namespace("rust"));
    out.begin_block(Block::InlineNamespace("cxxbridge1"));
    writeln!(out, "// #include \"rust/cxx.h\"");

    ifndef::write(out, builtin.panic, "CXXBRIDGE1_PANIC");

    if builtin.rust_string {
        out.next_section();
        writeln!(out, "struct unsafe_bitcopy_t;");
    }

    if builtin.friend_impl {
        out.begin_block(Block::AnonymousNamespace);
        writeln!(out, "template <typename T>");
        writeln!(out, "class impl;");
        out.end_block(Block::AnonymousNamespace);
    }

    out.next_section();
    if builtin.rust_str && !builtin.rust_string {
        writeln!(out, "class String;");
    }
    if builtin.layout && !builtin.opaque {
        writeln!(out, "class Opaque;");
    }

    if builtin.rust_slice {
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "::std::size_t size_of();");
        writeln!(out, "template <typename T>");
        writeln!(out, "::std::size_t align_of();");
    }

    ifndef::write(out, builtin.rust_string, "CXXBRIDGE1_RUST_STRING");
    ifndef::write(out, builtin.rust_str, "CXXBRIDGE1_RUST_STR");
    ifndef::write(out, builtin.rust_slice, "CXXBRIDGE1_RUST_SLICE");
    ifndef::write(out, builtin.rust_box, "CXXBRIDGE1_RUST_BOX");
    ifndef::write(out, builtin.unsafe_bitcopy, "CXXBRIDGE1_RUST_BITCOPY");
    ifndef::write(out, builtin.rust_vec, "CXXBRIDGE1_RUST_VEC");
    ifndef::write(out, builtin.rust_fn, "CXXBRIDGE1_RUST_FN");
    ifndef::write(out, builtin.rust_error, "CXXBRIDGE1_RUST_ERROR");
    ifndef::write(out, builtin.rust_isize, "CXXBRIDGE1_RUST_ISIZE");
    ifndef::write(out, builtin.opaque, "CXXBRIDGE1_RUST_OPAQUE");
    ifndef::write(out, builtin.is_complete, "CXXBRIDGE1_IS_COMPLETE");
    ifndef::write(out, builtin.layout, "CXXBRIDGE1_LAYOUT");
    ifndef::write(out, builtin.relocatable, "CXXBRIDGE1_RELOCATABLE");

    if builtin.rust_str_new_unchecked {
        out.next_section();
        writeln!(out, "class Str::uninit {{}};");
        writeln!(out, "inline Str::Str(uninit) noexcept {{}}");
    }

    if builtin.rust_slice_new {
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "class Slice<T>::uninit {{}};");
        writeln!(out, "template <typename T>");
        writeln!(out, "inline Slice<T>::Slice(uninit) noexcept {{}}");
    }

    out.begin_block(Block::Namespace("detail"));

    if builtin.maybe_uninit {
        include.cstddef = true;
        include.new = true;
        out.next_section();
        writeln!(out, "template <typename T, typename = void *>");
        writeln!(out, "struct operator_new {{");
        writeln!(
            out,
            "  void *operator()(::std::size_t sz) {{ return ::operator new(sz); }}",
        );
        writeln!(out, "}};");
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(
            out,
            "struct operator_new<T, decltype(T::operator new(sizeof(T)))> {{",
        );
        writeln!(
            out,
            "  void *operator()(::std::size_t sz) {{ return T::operator new(sz); }}",
        );
        writeln!(out, "}};");
    }

    out.end_block(Block::Namespace("detail"));

    if builtin.manually_drop {
        out.next_section();
        include.utility = true;
        writeln!(out, "template <typename T>");
        writeln!(out, "union ManuallyDrop {{");
        writeln!(out, "  T value;");
        writeln!(
            out,
            "  ManuallyDrop(T &&value) : value(::std::move(value)) {{}}",
        );
        writeln!(out, "  ~ManuallyDrop() {{}}");
        writeln!(out, "}};");
    }

    if builtin.maybe_uninit {
        include.cstddef = true;
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "union MaybeUninit {{");
        writeln!(out, "  T value;");
        writeln!(
            out,
            "  void *operator new(::std::size_t sz) {{ return detail::operator_new<T>{{}}(sz); }}",
        );
        writeln!(out, "  MaybeUninit() {{}}");
        writeln!(out, "  ~MaybeUninit() {{}}");
        writeln!(out, "}};");
    }

    out.begin_block(Block::AnonymousNamespace);

    if builtin.repr_fat {
        include.array = true;
        include.cstdint = true;
        out.next_section();
        out.begin_block(Block::Namespace("repr"));
        writeln!(out, "using Fat = ::std::array<::std::uintptr_t, 2>;");
        out.end_block(Block::Namespace("repr"));
    }

    if builtin.ptr_len {
        include.cstddef = true;
        out.next_section();
        out.begin_block(Block::Namespace("repr"));
        writeln!(out, "struct PtrLen final {{");
        writeln!(out, "  void *ptr;");
        writeln!(out, "  ::std::size_t len;");
        writeln!(out, "}};");
        out.end_block(Block::Namespace("repr"));
    }

    if builtin.rust_str_new_unchecked || builtin.rust_str_repr {
        out.next_section();
        writeln!(out, "template <>");
        writeln!(out, "class impl<Str> final {{");
        writeln!(out, "public:");
        if builtin.rust_str_new_unchecked {
            writeln!(
                out,
                "  static Str new_unchecked(repr::Fat repr) noexcept {{",
            );
            writeln!(out, "    Str str = Str::uninit{{}};");
            writeln!(out, "    str.repr = repr;");
            writeln!(out, "    return str;");
            writeln!(out, "  }}");
        }
        if builtin.rust_str_repr {
            writeln!(out, "  static repr::Fat repr(Str str) noexcept {{");
            writeln!(out, "    return str.repr;");
            writeln!(out, "  }}");
        }
        writeln!(out, "}};");
    }

    if builtin.rust_slice_new || builtin.rust_slice_repr {
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "class impl<Slice<T>> final {{");
        writeln!(out, "public:");
        if builtin.rust_slice_new {
            writeln!(out, "  static Slice<T> slice(repr::Fat repr) noexcept {{");
            writeln!(out, "    Slice<T> slice = typename Slice<T>::uninit{{}};");
            writeln!(out, "    slice.repr = repr;");
            writeln!(out, "    return slice;");
            writeln!(out, "  }}");
        }
        if builtin.rust_slice_repr {
            writeln!(out, "  static repr::Fat repr(Slice<T> slice) noexcept {{");
            writeln!(out, "    return slice.repr;");
            writeln!(out, "  }}");
        }
        writeln!(out, "}};");
    }

    if builtin.rust_error {
        out.next_section();
        writeln!(out, "template <>");
        writeln!(out, "class impl<Error> final {{");
        writeln!(out, "public:");
        writeln!(out, "  static Error error(repr::PtrLen repr) noexcept {{");
        writeln!(out, "    Error error;");
        writeln!(out, "    error.msg = static_cast<const char *>(repr.ptr);");
        writeln!(out, "    error.len = repr.len;");
        writeln!(out, "    return error;");
        writeln!(out, "  }}");
        writeln!(out, "}};");
    }

    if builtin.deleter_if {
        out.next_section();
        writeln!(out, "template <bool> struct deleter_if {{");
        writeln!(out, "  template <typename T> void operator()(T *) {{}}");
        writeln!(out, "}};");
        out.next_section();
        writeln!(out, "template <> struct deleter_if<true> {{");
        writeln!(
            out,
            "  template <typename T> void operator()(T *ptr) {{ ptr->~T(); }}",
        );
        writeln!(out, "}};");
    }

    out.end_block(Block::AnonymousNamespace);
    out.end_block(Block::InlineNamespace("cxxbridge1"));

    if builtin.trycatch {
        out.begin_block(Block::Namespace("behavior"));
        include.exception = true;
        include.type_traits = true;
        include.utility = true;
        writeln!(out, "class missing {{}};");
        writeln!(out, "missing trycatch(...);");
        writeln!(out);
        writeln!(out, "template <typename Try, typename Fail>");
        writeln!(out, "static typename ::std::enable_if<");
        writeln!(
            out,
            "    ::std::is_same<decltype(trycatch(::std::declval<Try>(), ::std::declval<Fail>())),",
        );
        writeln!(out, "                 missing>::value>::type");
        writeln!(out, "trycatch(Try &&func, Fail &&fail) noexcept try {{");
        writeln!(out, "  func();");
        writeln!(out, "}} catch (const ::std::exception &e) {{");
        writeln!(out, "  fail(e.what());");
        writeln!(out, "}}");
        out.end_block(Block::Namespace("behavior"));
    }

    out.end_block(Block::Namespace("rust"));

    if builtin.exception {
        include.cstddef = true;
        out.begin_block(Block::ExternC);
        writeln!(
            out,
            "const char *cxxbridge1$exception(const char *, ::std::size_t);",
        );
        out.end_block(Block::ExternC);
    }
}
<commit_msg>Omit most builtins if bridge explicitly includes "rust/cxx.h"<commit_after>use crate::gen::block::Block;
use crate::gen::ifndef;
use crate::gen::out::{Content, OutFile};

#[derive(Default, PartialEq)]
pub struct Builtins<'a> {
    pub panic: bool,
    pub rust_string: bool,
    pub rust_str: bool,
    pub rust_slice: bool,
    pub rust_box: bool,
    pub rust_vec: bool,
    pub rust_fn: bool,
    pub rust_isize: bool,
    pub opaque: bool,
    pub layout: bool,
    pub unsafe_bitcopy: bool,
    pub rust_error: bool,
    pub manually_drop: bool,
    pub maybe_uninit: bool,
    pub trycatch: bool,
    pub ptr_len: bool,
    pub repr_fat: bool,
    pub rust_str_new_unchecked: bool,
    pub rust_str_repr: bool,
    pub rust_slice_new: bool,
    pub rust_slice_repr: bool,
    pub exception: bool,
    pub relocatable: bool,
    pub friend_impl: bool,
    pub is_complete: bool,
    pub deleter_if: bool,
    pub content: Content<'a>,
}

impl<'a> Builtins<'a> {
    pub fn new() -> Self {
        Builtins::default()
    }
}

pub(super) fn write(out: &mut OutFile) {
    if out.builtin == Default::default() {
        return;
    }

    let include = &mut out.include;
    let builtin = &mut out.builtin;
    let out = &mut builtin.content;

    let cxx_header = include
        .custom
        .iter()
        .any(|header| header.path == "rust/cxx.h" || header.path == "rust\\cxx.h");

    if builtin.rust_string {
        include.array = true;
        include.cstdint = true;
        include.string = true;
    }

    if builtin.rust_str {
        include.array = true;
        include.cstdint = true;
        include.string = true;
        builtin.friend_impl = true;
    }

    if builtin.rust_vec {
        include.algorithm = true;
        include.array = true;
        include.cassert = true;
        include.cstddef = true;
        include.cstdint = true;
        include.initializer_list = true;
        include.iterator = true;
        include.new = true;
        include.type_traits = true;
        include.utility = true;
        builtin.panic = true;
        builtin.rust_slice = true;
        builtin.unsafe_bitcopy = true;
    }

    if builtin.rust_slice {
        include.array = true;
        include.cassert = true;
        include.cstddef = true;
        include.cstdint = true;
        include.iterator = true;
        include.type_traits = true;
        builtin.friend_impl = true;
        builtin.layout = true;
        builtin.panic = true;
    }

    if builtin.rust_box {
        include.new = true;
        include.type_traits = true;
        include.utility = true;
    }

    if builtin.rust_fn {
        include.utility = true;
    }

    if builtin.rust_error {
        include.exception = true;
        builtin.friend_impl = true;
    }

    if builtin.rust_isize {
        include.basetsd = true;
        include.sys_types = true;
    }

    if builtin.relocatable {
        include.type_traits = true;
    }

    if builtin.layout {
        include.type_traits = true;
        include.cstddef = true;
        builtin.is_complete = true;
    }

    if builtin.is_complete {
        include.cstddef = true;
        include.type_traits = true;
    }

    out.begin_block(Block::Namespace("rust"));
    out.begin_block(Block::InlineNamespace("cxxbridge1"));

    if !cxx_header {
        writeln!(out, "// #include \"rust/cxx.h\"");

        ifndef::write(out, builtin.panic, "CXXBRIDGE1_PANIC");

        if builtin.rust_string {
            out.next_section();
            writeln!(out, "struct unsafe_bitcopy_t;");
        }

        if builtin.friend_impl {
            out.begin_block(Block::AnonymousNamespace);
            writeln!(out, "template <typename T>");
            writeln!(out, "class impl;");
            out.end_block(Block::AnonymousNamespace);
        }

        out.next_section();
        if builtin.rust_str && !builtin.rust_string {
            writeln!(out, "class String;");
        }
        if builtin.layout && !builtin.opaque {
            writeln!(out, "class Opaque;");
        }

        if builtin.rust_slice {
            out.next_section();
            writeln!(out, "template <typename T>");
            writeln!(out, "::std::size_t size_of();");
            writeln!(out, "template <typename T>");
            writeln!(out, "::std::size_t align_of();");
        }

        ifndef::write(out, builtin.rust_string, "CXXBRIDGE1_RUST_STRING");
        ifndef::write(out, builtin.rust_str, "CXXBRIDGE1_RUST_STR");
        ifndef::write(out, builtin.rust_slice, "CXXBRIDGE1_RUST_SLICE");
        ifndef::write(out, builtin.rust_box, "CXXBRIDGE1_RUST_BOX");
        ifndef::write(out, builtin.unsafe_bitcopy, "CXXBRIDGE1_RUST_BITCOPY");
        ifndef::write(out, builtin.rust_vec, "CXXBRIDGE1_RUST_VEC");
        ifndef::write(out, builtin.rust_fn, "CXXBRIDGE1_RUST_FN");
        ifndef::write(out, builtin.rust_error, "CXXBRIDGE1_RUST_ERROR");
        ifndef::write(out, builtin.rust_isize, "CXXBRIDGE1_RUST_ISIZE");
        ifndef::write(out, builtin.opaque, "CXXBRIDGE1_RUST_OPAQUE");
        ifndef::write(out, builtin.is_complete, "CXXBRIDGE1_IS_COMPLETE");
        ifndef::write(out, builtin.layout, "CXXBRIDGE1_LAYOUT");
        ifndef::write(out, builtin.relocatable, "CXXBRIDGE1_RELOCATABLE");
    }

    if builtin.rust_str_new_unchecked {
        out.next_section();
        writeln!(out, "class Str::uninit {{}};");
        writeln!(out, "inline Str::Str(uninit) noexcept {{}}");
    }

    if builtin.rust_slice_new {
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "class Slice<T>::uninit {{}};");
        writeln!(out, "template <typename T>");
        writeln!(out, "inline Slice<T>::Slice(uninit) noexcept {{}}");
    }

    out.begin_block(Block::Namespace("detail"));

    if builtin.maybe_uninit {
        include.cstddef = true;
        include.new = true;
        out.next_section();
        writeln!(out, "template <typename T, typename = void *>");
        writeln!(out, "struct operator_new {{");
        writeln!(
            out,
            "  void *operator()(::std::size_t sz) {{ return ::operator new(sz); }}",
        );
        writeln!(out, "}};");
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(
            out,
            "struct operator_new<T, decltype(T::operator new(sizeof(T)))> {{",
        );
        writeln!(
            out,
            "  void *operator()(::std::size_t sz) {{ return T::operator new(sz); }}",
        );
        writeln!(out, "}};");
    }

    out.end_block(Block::Namespace("detail"));

    if builtin.manually_drop {
        out.next_section();
        include.utility = true;
        writeln!(out, "template <typename T>");
        writeln!(out, "union ManuallyDrop {{");
        writeln!(out, "  T value;");
        writeln!(
            out,
            "  ManuallyDrop(T &&value) : value(::std::move(value)) {{}}",
        );
        writeln!(out, "  ~ManuallyDrop() {{}}");
        writeln!(out, "}};");
    }

    if builtin.maybe_uninit {
        include.cstddef = true;
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "union MaybeUninit {{");
        writeln!(out, "  T value;");
        writeln!(
            out,
            "  void *operator new(::std::size_t sz) {{ return detail::operator_new<T>{{}}(sz); }}",
        );
        writeln!(out, "  MaybeUninit() {{}}");
        writeln!(out, "  ~MaybeUninit() {{}}");
        writeln!(out, "}};");
    }

    out.begin_block(Block::AnonymousNamespace);

    if builtin.repr_fat {
        include.array = true;
        include.cstdint = true;
        out.next_section();
        out.begin_block(Block::Namespace("repr"));
        writeln!(out, "using Fat = ::std::array<::std::uintptr_t, 2>;");
        out.end_block(Block::Namespace("repr"));
    }

    if builtin.ptr_len {
        include.cstddef = true;
        out.next_section();
        out.begin_block(Block::Namespace("repr"));
        writeln!(out, "struct PtrLen final {{");
        writeln!(out, "  void *ptr;");
        writeln!(out, "  ::std::size_t len;");
        writeln!(out, "}};");
        out.end_block(Block::Namespace("repr"));
    }

    if builtin.rust_str_new_unchecked || builtin.rust_str_repr {
        out.next_section();
        writeln!(out, "template <>");
        writeln!(out, "class impl<Str> final {{");
        writeln!(out, "public:");
        if builtin.rust_str_new_unchecked {
            writeln!(
                out,
                "  static Str new_unchecked(repr::Fat repr) noexcept {{",
            );
            writeln!(out, "    Str str = Str::uninit{{}};");
            writeln!(out, "    str.repr = repr;");
            writeln!(out, "    return str;");
            writeln!(out, "  }}");
        }
        if builtin.rust_str_repr {
            writeln!(out, "  static repr::Fat repr(Str str) noexcept {{");
            writeln!(out, "    return str.repr;");
            writeln!(out, "  }}");
        }
        writeln!(out, "}};");
    }

    if builtin.rust_slice_new || builtin.rust_slice_repr {
        out.next_section();
        writeln!(out, "template <typename T>");
        writeln!(out, "class impl<Slice<T>> final {{");
        writeln!(out, "public:");
        if builtin.rust_slice_new {
            writeln!(out, "  static Slice<T> slice(repr::Fat repr) noexcept {{");
            writeln!(out, "    Slice<T> slice = typename Slice<T>::uninit{{}};");
            writeln!(out, "    slice.repr = repr;");
            writeln!(out, "    return slice;");
            writeln!(out, "  }}");
        }
        if builtin.rust_slice_repr {
            writeln!(out, "  static repr::Fat repr(Slice<T> slice) noexcept {{");
            writeln!(out, "    return slice.repr;");
            writeln!(out, "  }}");
        }
        writeln!(out, "}};");
    }

    if builtin.rust_error {
        out.next_section();
        writeln!(out, "template <>");
        writeln!(out, "class impl<Error> final {{");
        writeln!(out, "public:");
        writeln!(out, "  static Error error(repr::PtrLen repr) noexcept {{");
        writeln!(out, "    Error error;");
        writeln!(out, "    error.msg = static_cast<const char *>(repr.ptr);");
        writeln!(out, "    error.len = repr.len;");
        writeln!(out, "    return error;");
        writeln!(out, "  }}");
        writeln!(out, "}};");
    }

    if builtin.deleter_if {
        out.next_section();
        writeln!(out, "template <bool> struct deleter_if {{");
        writeln!(out, "  template <typename T> void operator()(T *) {{}}");
        writeln!(out, "}};");
        out.next_section();
        writeln!(out, "template <> struct deleter_if<true> {{");
        writeln!(
            out,
            "  template <typename T> void operator()(T *ptr) {{ ptr->~T(); }}",
        );
        writeln!(out, "}};");
    }

    out.end_block(Block::AnonymousNamespace);
    out.end_block(Block::InlineNamespace("cxxbridge1"));

    if builtin.trycatch {
        out.begin_block(Block::Namespace("behavior"));
        include.exception = true;
        include.type_traits = true;
        include.utility = true;
        writeln!(out, "class missing {{}};");
        writeln!(out, "missing trycatch(...);");
        writeln!(out);
        writeln!(out, "template <typename Try, typename Fail>");
        writeln!(out, "static typename ::std::enable_if<");
        writeln!(
            out,
            "    ::std::is_same<decltype(trycatch(::std::declval<Try>(), ::std::declval<Fail>())),",
        );
        writeln!(out, "                 missing>::value>::type");
        writeln!(out, "trycatch(Try &&func, Fail &&fail) noexcept try {{");
        writeln!(out, "  func();");
        writeln!(out, "}} catch (const ::std::exception &e) {{");
        writeln!(out, "  fail(e.what());");
        writeln!(out, "}}");
        out.end_block(Block::Namespace("behavior"));
    }

    out.end_block(Block::Namespace("rust"));

    if builtin.exception {
        include.cstddef = true;
        out.begin_block(Block::ExternC);
        writeln!(
            out,
            "const char *cxxbridge1$exception(const char *, ::std::size_t);",
        );
        out.end_block(Block::ExternC);
    }
}
<|endoftext|>


<commit_before>extern crate torchrs;

use torchrs::nn::{Module, Conv2d, Linear};

use torchrs::nn::functional::{max_pool2d, relu, dropout, dropout2d, log_softmax};
#[derive(Serialize, Deserialize, Debug, ModuleParse)]
struct Net<'a> {
    delegate: nn::Module<'a>,
    conv1: Conv2d<'a>,
    conv2: Conv2d<'a>,
    fc1: Linear<'a>,
    fc2: Linear<'a>,
}

impl Net<'a> {
    pub fn new() -> Net<'a> {
        let t = Net {
        delegate: Module::new(),
        conv1: Conv2d::build(1, 10, 5).done(),
        conv2: Conv2d::build(10, 20, 5).done(),
        fc1: Linear::build(320, 50).done(),
        fc2: Linear::build(50, 10).done(),
        };
        t.init_module();
        t
    }
}
// The forward operations could take on one of two implementations.
// The first supporting a near verbatim version of the python
// implementation, and the second supporting a slightly more
// idiomatic to Rust method chaining.

// a) as a near verbatim implementation of the python version
impl <'a>ModIntf<'a> for Net<'a> {
    fn forward(&mut self, args: &[&mut Tensor]) -> [&mut Tensor] {
        let training = self.delegate.training;
        let x = relu(max_pool2d(self.conv1(&args[0]), 2), false);
        let x = relu(max_pool2d(dropout2d(self.conv2(&x), training, 0.5), 2), false);
        let x = x.view(-1, 320);
        let x = relu(self.fc1(&x), false);
        let x = dropout(&x, training, 0.5);
        let x = self.fc2(&x);
        [log_softmax(&x)]
    }
 }

fn main () {

}<commit_msg>incremental fixes<commit_after>extern crate torchrs;
#[macro_use]
extern crate modparse_derive;

use torchrs::nn::{Module, Conv2d, Linear};
use torchrs::nn::modules::module::*;
use torchrs::tensor::Tensor;

use torchrs::nn::functional::{max_pool2d, relu, dropout, dropout2d, log_softmax};
#[derive(Debug, ModParse)]
struct Net<'a> {
    delegate: Module<'a>,
    conv1: Conv2d<'a>,
    conv2: Conv2d<'a>,
    fc1: Linear<'a>,
    fc2: Linear<'a>,
}

impl <'a>Net<'a> {
    pub fn new() -> Net<'a> {
        let t = Net {
        delegate: Module::new(),
        conv1: Conv2d::build(1, 10, 5).done(),
        conv2: Conv2d::build(10, 20, 5).done(),
        fc1: Linear::build(320, 50).done(),
        fc2: Linear::build(50, 10).done(),
        };
        t.init_module();
        t
    }
}
// The forward operations could take on one of two implementations.
// The first supporting a near verbatim version of the python
// implementation, and the second supporting a slightly more
// idiomatic to Rust method chaining.

// a) as a near verbatim implementation of the python version
impl <'a>ModIntf<'a> for Net<'a> {
    fn forward<'b>(&mut self, args: &'b [&'b mut Tensor]) -> &'b [&'b mut Tensor] {
        let training = self.delegate.training;
        let x = relu(max_pool2d(self.conv1(&args), 2), false);
        let x = relu(max_pool2d(dropout2d(self.conv2(&x), training, 0.5), 2), false);
        let x = x.view(-1, 320);
        let x = relu(self.fc1(&x), false);
        let x = dropout(&x, training, 0.5);
        let x = self.fc2(&x);
        log_softmax(&x)
    }
    fn delegate(&mut self) -> &mut Module<'a> {&mut self.delegate}

 }

fn main () {

}<|endoftext|>


<commit_before>/// This is a doubly-linked list implementation with forward pointers being owners and backward
/// pointers being unsafe pointers. The goal is to write the unsafe code involving the backward
/// links as similarly as the safe code for the forward links to avoid rampant stupidity.

use std::borrow::Borrow;
use std::borrow::BorrowMut;
use std::iter::IntoIterator;
use std::ptr;

////////////////////////////////////////////////////////////////////////////////
// List implementation

pub struct List<T> {
    head: Link<T>,
    tail: LinkPtr<T>,
}

type Link<T> = Option<Box<Node<T>>>;
type LinkPtr<T> = *const Node<T>;

struct Node<T> {
    elem: T,
    next: Link<T>,
    prev: LinkPtr<T>,
}

////////////////////////////////////////////////////////////
// Referential equality helpers
//
// While Option<&T> is Copy, Option<&mut T> is not, so taking Options by reference for consistency.

fn eq_ref_opt<T>(ref1: &T, opt_ref2: &Option<&T>) -> bool {
    match opt_ref2 {
        // Need to convert to *const for referential equality.
        &Some(ref ref2) => ref1 as *const T == *ref2 as *const T,
        &None => false
    }
}

fn eq_mut_ref_opt<T>(ref1: &mut T, opt_ref2: &Option<&mut T>) -> bool {
    match opt_ref2 {
        // Need to convert to *const for referential equality.
        &Some(ref ref2) => ref1 as *const T == *ref2 as *const T,
        &None => false
    }
}

////////////////////////////////////////////////////////////
// Box to ptr conversion

trait BoxHelpers<T> {
    fn to_ptr(&self) -> *const T;
}

impl<T> BoxHelpers<T> for Box<T> {
    fn to_ptr(&self) -> *const T {
        Borrow::<T>::borrow(self) as *const T
    }
}

////////////////////////////////////////////////////////////
// Conversions to Option<&>

trait OptionRef<T> {
    fn to_ref(&self) -> Option<&T>;
    fn to_mut(&mut self) -> Option<&mut T>;
}

// Option<Box> -> Option<&>. In fact, can be used instead of as_ref() and as_mut() in most places.
impl<T, B: Borrow<T> + BorrowMut<T>> OptionRef<T> for Option<B> {
    fn to_ref(&self) -> Option<&T> {
        self.as_ref().take().map(|borrowable| {borrowable.borrow()})
    }
    fn to_mut(&mut self) -> Option<&mut T> {
        self.as_mut().take().map(|borrowable| {borrowable.borrow_mut()})
    }
}

// Make unsafe pointers behave similar to Option<Box> above. This is unsafe because the output
// reference isn't unbounded and the caller is responsible for bounding it appropriately.
trait UnsafeOptionRef<T> {
    unsafe fn to_ref<'b>(self) -> Option<&'b T>;
    unsafe fn to_mut<'b>(self) -> Option<&'b mut T>;
}

impl<T> UnsafeOptionRef<T> for *const T {
    unsafe fn to_ref<'b>(self) -> Option<&'b T> {
        match self as usize {
            0 => None,
            _ => Some(&*self)
        }
    }
    unsafe fn to_mut<'b>(self) -> Option<&'b mut T> {
        match self as usize {
            0 => None,
            _ => Some(&mut *(self as *mut _))
        }
    }
}

////////////////////////////////////////////////////////////
/// Doubly-linked list

impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None, tail: ptr::null() }
    }

    // PUSH
    pub fn push_front(&mut self, elem: T) {
        let mut node_box = Box::new(Node {
            elem: elem,
            next: self.head.take(),
            prev: ptr::null()
        });
        let node_ptr = node_box.to_ptr();
        match node_box.next.as_mut() { // What self.head used to be before it was take()n above.
            None => self.tail = node_ptr,
            Some(old_head_ref) => old_head_ref.prev = node_ptr
        }
        self.head = Some(node_box);
    }

    pub fn push_back(&mut self, elem: T) {
        let node_box = Box::new(Node {
            elem: elem,
            next: None,
            prev: self.tail
        });
        let node_ptr = node_box.to_ptr();
        match unsafe { self.tail.to_mut() } {
            None => self.head = Some(node_box),
            Some(old_tail_ref) => old_tail_ref.next = Some(node_box)
        }
        self.tail = node_ptr;
    }

    // POP
    pub fn pop_front(&mut self) -> Option<T> {
        self.head.take().map(|node_box| {
            let node = *node_box;
            self.head = node.next;
            match self.head.as_mut() {
                None => self.tail = ptr::null(),
                Some(node_box) => node_box.prev = ptr::null()
            }
            node.elem
        })
    }

    pub fn pop_back(&mut self) -> Option<T> {
        // Subtle differences with pop_front() are primarily because the disconnection from the
        // owner via take() happens later.
        unsafe { self.tail.to_ref() }.map(|node_ref| {
            self.tail = node_ref.prev;
            let node_opt = match unsafe { self.tail.to_mut() } {
                None => self.head.take(),
                Some(node_ref) => node_ref.next.take()
            };
            node_opt.unwrap().elem // Ideally, should use unwrap_unchecked().
        })
    }

    // PEEK
    pub fn peek_front(&self) -> Option<&T> {
        self.head.as_ref().map(|node| { &node.elem })
    }

    pub fn peek_back(&self) -> Option<&T> {
        unsafe { self.tail.to_ref() }.map(|node| { &node.elem })
    }

    // PEEK MUT
    pub fn peek_front_mut(&mut self) -> Option<&mut T> {
        self.head.as_mut().map(|node| { &mut node.elem })
    }

    pub fn peek_back_mut(&mut self) -> Option<&mut T> {
        unsafe { self.tail.to_mut() }.map(|node| { &mut node.elem })
    }

    // ITER
    pub fn iter(&self) -> Iter<T> {
        Iter {
            front_link: self.head.to_ref(),
            back_link: unsafe { self.tail.to_ref() }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// By-reference Iter

pub struct Iter<'a, T: 'a> {
    front_link: Option<&'a Node<T>>,
    back_link: Option<&'a Node<T>>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.front_link.take().map(|node_ref| {
            if eq_ref_opt(node_ref, &self.back_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.front_link = node_ref.next.to_ref()
            }
            &node_ref.elem
        })
    }
}

impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.back_link.take().map(|node_ref| {
            if eq_ref_opt(node_ref, &self.front_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.back_link = unsafe { node_ref.prev.to_ref() }
            }
            &node_ref.elem
        })
    }
}

////////////////////////////////////////////////////////////////////////////////
// IntoIterator

pub struct ListIntoIterator<T> {
    list: List<T>,
}

impl<T> Iterator for ListIntoIterator<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.list.pop_front()
    }
}

impl<T> DoubleEndedIterator for ListIntoIterator<T> {
    fn next_back(&mut self) -> Option<T> {
        self.list.pop_back()
    }
}

impl<T> IntoIterator for List<T> {
    type Item = T;
    type IntoIter = ListIntoIterator<T>;

    fn into_iter(self) -> ListIntoIterator<T> {
        ListIntoIterator { list: self }
    }
}

impl<'a, T> IntoIterator for &'a List<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

////////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod test {
    use super::List;

    #[test]
    fn test_push_pop_front() {
        let mut list = List::new();
        list.push_front(1);
        assert_eq!(Some(&1), list.peek_front());
        list.push_front(2);
        assert_eq!(Some(&2), list.peek_front());
        list.push_front(3);
        assert_eq!(Some(&3), list.peek_front());
        assert_eq!(Some(3), list.pop_front());
        assert_eq!(Some(2), list.pop_front());
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(None, list.pop_front());
    }

    #[test]
    fn test_push_pop_back() {
        let mut list = List::new();
        list.push_back(1);
        assert_eq!(Some(&1), list.peek_back());
        list.push_back(2);
        assert_eq!(Some(&2), list.peek_back());
        list.push_back(3);
        assert_eq!(Some(&3), list.peek_back());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(2), list.pop_back());
        assert_eq!(Some(1), list.pop_back());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_push_pop_both() {
        let mut list = List::new();
        list.push_back(2);
        assert_eq!(Some(&2), list.peek_back());
        list.push_front(1);
        assert_eq!(Some(&1), list.peek_front());
        assert_eq!(Some(&2), list.peek_back());
        list.push_back(3);
        assert_eq!(Some(&1), list.peek_front());
        assert_eq!(Some(&3), list.peek_back());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(Some(2), list.pop_front());
        assert_eq!(None, list.pop_front());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_push_pop_crash() {
        let mut list = List::new();
        list.push_front(1);
        list.push_front(2);
        list.push_front(3);
        let mut i = 3;
        for val in list {
            assert_eq!(i, val);
            i -= 1;
        }

        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(2), list.pop_back());
        assert_eq!(None, list.pop_front());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_into_iter() {
        let mut list = List::new();
        list.push_front(1);
        list.push_front(2);
        list.push_front(3);
        let mut i = 3;
        for val in list {
            assert_eq!(i, val);
            i -= 1;
        }

        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        let mut iter = list.into_iter();
        assert_eq!(Some(1), iter.next());
        assert_eq!(Some(3), iter.next_back());
        assert_eq!(Some(2), iter.next_back());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());
    }

    #[test]
    fn test_iter() {
        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        let mut iter = list.iter();
        assert_eq!(Some(&1), iter.next());
        assert_eq!(Some(&3), iter.next_back());
        assert_eq!(Some(&2), iter.next_back());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());

        let mut iter = list.iter();
        assert_eq!(Some(&3), iter.next_back());
        assert_eq!(Some(&1), iter.next());
        assert_eq!(Some(&2), iter.next());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());

        let mut i = 1;
        for val in &list {
            assert_eq!(i, *val);
            i += 1;
        }
    }
}

<commit_msg>Doubly-linked list: Added mutable iterator.<commit_after>/// This is a doubly-linked list implementation with forward pointers being owners and backward
/// pointers being unsafe pointers. The goal is to write the unsafe code involving the backward
/// links as similarly as the safe code for the forward links to avoid rampant stupidity.

use std::borrow::Borrow;
use std::borrow::BorrowMut;
use std::iter::IntoIterator;
use std::ptr;

////////////////////////////////////////////////////////////////////////////////
// List implementation

pub struct List<T> {
    head: Link<T>,
    tail: LinkPtr<T>,
}

type Link<T> = Option<Box<Node<T>>>;
type LinkPtr<T> = *const Node<T>;

struct Node<T> {
    elem: T,
    next: Link<T>,
    prev: LinkPtr<T>,
}

////////////////////////////////////////////////////////////
// Referential equality helpers
//
// While Option<&T> is Copy, Option<&mut T> is not, so taking Options by reference for consistency.

fn eq_ref_opt<T>(ref1: &T, opt_ref2: &Option<&T>) -> bool {
    match opt_ref2 {
        // Need to convert to *const for referential equality.
        &Some(ref ref2) => ref1 as *const T == *ref2 as *const T,
        &None => false
    }
}

fn eq_mut_ref_opt<T>(ref1: &mut T, opt_ref2: &Option<&mut T>) -> bool {
    match opt_ref2 {
        // Need to convert to *const for referential equality.
        &Some(ref ref2) => ref1 as *const T == *ref2 as *const T,
        &None => false
    }
}

////////////////////////////////////////////////////////////
// Box to ptr conversion

trait BoxHelpers<T> {
    fn to_ptr(&self) -> *const T;
}

impl<T> BoxHelpers<T> for Box<T> {
    fn to_ptr(&self) -> *const T {
        Borrow::<T>::borrow(self) as *const T
    }
}

////////////////////////////////////////////////////////////
// Conversions to Option<&>

trait OptionRef<T> {
    fn to_ref(&self) -> Option<&T>;
    fn to_mut(&mut self) -> Option<&mut T>;
}

// Option<Box> -> Option<&>. In fact, can be used instead of as_ref() and as_mut() in most places.
impl<T, B: Borrow<T> + BorrowMut<T>> OptionRef<T> for Option<B> {
    fn to_ref(&self) -> Option<&T> {
        self.as_ref().take().map(|borrowable| {borrowable.borrow()})
    }
    fn to_mut(&mut self) -> Option<&mut T> {
        self.as_mut().take().map(|borrowable| {borrowable.borrow_mut()})
    }
}

// Make unsafe pointers behave similar to Option<Box> above. This is unsafe because the output
// reference isn't unbounded and the caller is responsible for bounding it appropriately.
trait UnsafeOptionRef<T> {
    unsafe fn to_ref<'b>(self) -> Option<&'b T>;
    unsafe fn to_mut<'b>(self) -> Option<&'b mut T>;
}

impl<T> UnsafeOptionRef<T> for *const T {
    unsafe fn to_ref<'b>(self) -> Option<&'b T> {
        match self as usize {
            0 => None,
            _ => Some(&*self)
        }
    }
    unsafe fn to_mut<'b>(self) -> Option<&'b mut T> {
        match self as usize {
            0 => None,
            _ => Some(&mut *(self as *mut _))
        }
    }
}

////////////////////////////////////////////////////////////
/// Doubly-linked list

impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None, tail: ptr::null() }
    }

    // PUSH
    pub fn push_front(&mut self, elem: T) {
        let mut node_box = Box::new(Node {
            elem: elem,
            next: self.head.take(),
            prev: ptr::null()
        });
        let node_ptr = node_box.to_ptr();
        match node_box.next.as_mut() { // What self.head used to be before it was take()n above.
            None => self.tail = node_ptr,
            Some(old_head_ref) => old_head_ref.prev = node_ptr
        }
        self.head = Some(node_box);
    }

    pub fn push_back(&mut self, elem: T) {
        let node_box = Box::new(Node {
            elem: elem,
            next: None,
            prev: self.tail
        });
        let node_ptr = node_box.to_ptr();
        match unsafe { self.tail.to_mut() } {
            None => self.head = Some(node_box),
            Some(old_tail_ref) => old_tail_ref.next = Some(node_box)
        }
        self.tail = node_ptr;
    }

    // POP
    pub fn pop_front(&mut self) -> Option<T> {
        self.head.take().map(|node_box| {
            let node = *node_box;
            self.head = node.next;
            match self.head.as_mut() {
                None => self.tail = ptr::null(),
                Some(node_box) => node_box.prev = ptr::null()
            }
            node.elem
        })
    }

    pub fn pop_back(&mut self) -> Option<T> {
        // Subtle differences with pop_front() are primarily because the disconnection from the
        // owner via take() happens later.
        unsafe { self.tail.to_ref() }.map(|node_ref| {
            self.tail = node_ref.prev;
            let node_opt = match unsafe { self.tail.to_mut() } {
                None => self.head.take(),
                Some(node_ref) => node_ref.next.take()
            };
            node_opt.unwrap().elem // Ideally, should use unwrap_unchecked().
        })
    }

    // PEEK
    pub fn peek_front(&self) -> Option<&T> {
        self.head.as_ref().map(|node| { &node.elem })
    }

    pub fn peek_back(&self) -> Option<&T> {
        unsafe { self.tail.to_ref() }.map(|node| { &node.elem })
    }

    // PEEK MUT
    pub fn peek_front_mut(&mut self) -> Option<&mut T> {
        self.head.as_mut().map(|node| { &mut node.elem })
    }

    pub fn peek_back_mut(&mut self) -> Option<&mut T> {
        unsafe { self.tail.to_mut() }.map(|node| { &mut node.elem })
    }

    // ITER
    pub fn iter(&self) -> Iter<T> {
        Iter {
            front_link: self.head.to_ref(),
            back_link: unsafe { self.tail.to_ref() }
        }
    }

    pub fn iter_mut(&mut self) -> IterMut<T> {
        IterMut {
            front_link: self.head.to_mut(),
            back_link: unsafe { self.tail.to_mut() }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// By-reference Iter

pub struct Iter<'a, T: 'a> {
    front_link: Option<&'a Node<T>>,
    back_link: Option<&'a Node<T>>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.front_link.take().map(|node_ref| {
            if eq_ref_opt(node_ref, &self.back_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.front_link = node_ref.next.to_ref()
            }
            &node_ref.elem
        })
    }
}

impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.back_link.take().map(|node_ref| {
            if eq_ref_opt(node_ref, &self.front_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.back_link = unsafe { node_ref.prev.to_ref() }
            }
            &node_ref.elem
        })
    }
}

////////////////////////////////////////////////////////////////////////////////
// Mutable by-reference Iter

pub struct IterMut<'a, T: 'a> {
    front_link: Option<&'a mut Node<T>>,
    back_link: Option<&'a mut Node<T>>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        self.front_link.take().map(|node_ref| {
            if eq_mut_ref_opt(node_ref, &self.back_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.front_link = node_ref.next.to_mut()
            }
            &mut node_ref.elem
        })
    }
}

impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.back_link.take().map(|node_ref| {
            if eq_mut_ref_opt(node_ref, &self.front_link) { // If both ends collide, be DONE!
                self.front_link = None;
                self.back_link = None;
            } else {
                self.back_link = unsafe { node_ref.prev.to_mut() }
            }
            &mut node_ref.elem
        })
    }
}

////////////////////////////////////////////////////////////////////////////////
// IntoIterator

pub struct ListIntoIterator<T> {
    list: List<T>,
}

impl<T> Iterator for ListIntoIterator<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.list.pop_front()
    }
}

impl<T> DoubleEndedIterator for ListIntoIterator<T> {
    fn next_back(&mut self) -> Option<T> {
        self.list.pop_back()
    }
}

impl<T> IntoIterator for List<T> {
    type Item = T;
    type IntoIter = ListIntoIterator<T>;

    fn into_iter(self) -> ListIntoIterator<T> {
        ListIntoIterator { list: self }
    }
}

impl<'a, T> IntoIterator for &'a List<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

impl<'a, T> IntoIterator for &'a mut List<T> {
    type Item = &'a mut T;
    type IntoIter = IterMut<'a, T>;

    fn into_iter(self) -> IterMut<'a, T> {
        self.iter_mut()
    }
}

////////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod test {
    use super::List;

    #[test]
    fn test_push_pop_front() {
        let mut list = List::new();
        list.push_front(1);
        assert_eq!(Some(&1), list.peek_front());
        list.push_front(2);
        assert_eq!(Some(&2), list.peek_front());
        list.push_front(3);
        assert_eq!(Some(&3), list.peek_front());
        assert_eq!(Some(3), list.pop_front());
        assert_eq!(Some(2), list.pop_front());
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(None, list.pop_front());
    }

    #[test]
    fn test_push_pop_back() {
        let mut list = List::new();
        list.push_back(1);
        assert_eq!(Some(&1), list.peek_back());
        list.push_back(2);
        assert_eq!(Some(&2), list.peek_back());
        list.push_back(3);
        assert_eq!(Some(&3), list.peek_back());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(2), list.pop_back());
        assert_eq!(Some(1), list.pop_back());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_push_pop_both() {
        let mut list = List::new();
        list.push_back(2);
        assert_eq!(Some(&2), list.peek_back());
        list.push_front(1);
        assert_eq!(Some(&1), list.peek_front());
        assert_eq!(Some(&2), list.peek_back());
        list.push_back(3);
        assert_eq!(Some(&1), list.peek_front());
        assert_eq!(Some(&3), list.peek_back());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(Some(2), list.pop_front());
        assert_eq!(None, list.pop_front());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_push_pop_crash() {
        let mut list = List::new();
        list.push_front(1);
        list.push_front(2);
        list.push_front(3);
        let mut i = 3;
        for val in list {
            assert_eq!(i, val);
            i -= 1;
        }

        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        assert_eq!(Some(1), list.pop_front());
        assert_eq!(Some(3), list.pop_back());
        assert_eq!(Some(2), list.pop_back());
        assert_eq!(None, list.pop_front());
        assert_eq!(None, list.pop_back());
    }

    #[test]
    fn test_into_iter() {
        let mut list = List::new();
        list.push_front(1);
        list.push_front(2);
        list.push_front(3);
        let mut i = 3;
        for val in list {
            assert_eq!(i, val);
            i -= 1;
        }

        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        let mut iter = list.into_iter();
        assert_eq!(Some(1), iter.next());
        assert_eq!(Some(3), iter.next_back());
        assert_eq!(Some(2), iter.next_back());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());
    }

    #[test]
    fn test_iter() {
        let mut list = List::new();
        list.push_back(1);
        list.push_back(2);
        list.push_back(3);
        let mut iter = list.iter();
        assert_eq!(Some(&1), iter.next());
        assert_eq!(Some(&3), iter.next_back());
        assert_eq!(Some(&2), iter.next_back());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());

        let mut iter = list.iter();
        assert_eq!(Some(&3), iter.next_back());
        assert_eq!(Some(&1), iter.next());
        assert_eq!(Some(&2), iter.next());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());

        let mut i = 1;
        for val in &list {
            assert_eq!(i, *val);
            i += 1;
        }
    }

    #[test]
    fn test_iter_mut() {
        let mut list = List::new();
        list.push_front(1);
        list.push_front(2);
        list.push_front(3);
        let mut i = 3;
        for val in list.iter_mut() {
            assert_eq!(i, *val);
            *val = 3 - i;
            i -= 1;
        }
        let mut i = 0;
        for val in &mut list {
            assert_eq!(i, *val);
            *val = 3 - i;
            i += 1;
        }
        let mut i = 3;
        for val in &list {
            assert_eq!(i, *val);
            i -= 1;
        }
    }
}

<|endoftext|>


<commit_before>// Copyright © 2014, Peter Atashian
#![feature(old_path, std_misc)]

extern crate nx;

use nx::GenericNode;
use std::time::duration::Duration;

fn benchmark_suite() {
    fn load() -> nx::File {
        nx::File::open(&Path::new("Data.nx")).unwrap()
    }
    fn recurse(node: nx::Node) -> u32 {
        node.iter().fold(1, |&:a, b| a + recurse(b))
    }
    fn str_recurse(node: nx::Node) -> u32 {
        node.iter().fold(1, |&:a, b| {
            assert!(node.get(b.name()) == Some(b));
            a + str_recurse(b)
        })
    }
    fn test<F>(name: &str, count: u32, func: F) where F: Fn() -> u32 {
        let mut answer = 0;
        let mut vec = (0..count).map(|_| {
            Duration::span(|| answer = func()).num_microseconds().unwrap()
        }).collect::<Vec<_>>();
        vec.sort();
        let high = vec[vec.len() * 3 / 4];
        let slice = &vec[vec.len() * 1 / 4..vec.len() * 3 / 4];
        let mid = slice.iter().fold(0, |a, &b| a + b) / slice.len() as i64;
        let low = vec[0];
        println!("{}\t{}\t{}\t{}\t{}", name, high, mid, low, answer);
    }
    let file = nx::File::open(&Path::new("Data.nx")).unwrap();
    let node = file.root();
    println!("Name\t75%t\tM50%\tBest\tChecksum");
    test("Ld", 0x1000, || load().header().nodecount as u32);
    test("Re", 0x20, || recurse(node));
    test("LR", 0x20, || recurse(load().root()));
    test("SA", 0x20, || str_recurse(node));
}

fn main() {
    benchmark_suite()
}
<commit_msg>Update closure syntax<commit_after>// Copyright © 2014, Peter Atashian
#![feature(old_path, std_misc)]

extern crate nx;

use nx::GenericNode;
use std::time::duration::Duration;

fn benchmark_suite() {
    fn load() -> nx::File {
        nx::File::open(&Path::new("Data.nx")).unwrap()
    }
    fn recurse(node: nx::Node) -> u32 {
        node.iter().fold(1, |a, b| a + recurse(b))
    }
    fn str_recurse(node: nx::Node) -> u32 {
        node.iter().fold(1, |a, b| {
            assert!(node.get(b.name()) == Some(b));
            a + str_recurse(b)
        })
    }
    fn test<F>(name: &str, count: u32, func: F) where F: Fn() -> u32 {
        let mut answer = 0;
        let mut vec = (0..count).map(|_| {
            Duration::span(|| answer = func()).num_microseconds().unwrap()
        }).collect::<Vec<_>>();
        vec.sort();
        let high = vec[vec.len() * 3 / 4];
        let slice = &vec[vec.len() * 1 / 4..vec.len() * 3 / 4];
        let mid = slice.iter().fold(0, |a, &b| a + b) / slice.len() as i64;
        let low = vec[0];
        println!("{}\t{}\t{}\t{}\t{}", name, high, mid, low, answer);
    }
    let file = nx::File::open(&Path::new("Data.nx")).unwrap();
    let node = file.root();
    println!("Name\t75%t\tM50%\tBest\tChecksum");
    test("Ld", 0x1000, || load().header().nodecount as u32);
    test("Re", 0x20, || recurse(node));
    test("LR", 0x20, || recurse(load().root()));
    test("SA", 0x20, || str_recurse(node));
}

fn main() {
    benchmark_suite()
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate enum_map;

use enum_map::{Enum, EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::convert::Infallible;
use std::marker::PhantomData;

trait From<T>: Sized {
    fn from(_: T) -> Self {
        unreachable!();
    }
}

impl<T, U> From<T> for U {}

#[derive(Copy, Clone, Debug, Enum, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn test_clear() {
    let mut map = enum_map! { false => 1, true => 2 };
    map.clear();
    assert_eq!(map[true], 0);
    assert_eq!(map[false], 0);
}

#[test]
fn discriminants() {
    #[derive(Debug, Enum, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(Enum)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn into_iter_len() {
    assert_eq!(enum_map! { Example::A | _ => 0 }.into_iter().len(), 3);
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

#[test]
fn into_iter_u8() {
    assert_eq!(
        <EnumMap<_, _> as core::convert::From<_>>::from(|i: u8| i)
            .into_iter()
            .collect::<Vec<_>>(),
        (0..256).map(|x| (x as u8, x as u8)).collect::<Vec<_>>()
    );
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }
    .into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn values_rev_collect() {
    assert_eq!(
        vec![3, 2, 1],
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .values()
            .rev()
            .cloned()
            .collect::<Vec<_>>()
    );
}

#[test]
fn values_len() {
    assert_eq!(enum_map! { false => 0, true => 1 }.values().len(), 2);
}

#[test]
fn values_mut_next_back() {
    let mut map = enum_map! { false => 0, true => 1 };
    assert_eq!(map.values_mut().next_back(), Some(&mut 1));
}
#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(Enum)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map! {};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[test]
fn empty_infallible_map() {
    let void: EnumMap<Infallible, Infallible> = enum_map! {};
    assert!(void.is_empty());
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Enum<V> for X {
    type Array = [V; 1];
    const POSSIBLE_VALUES: usize = 1;

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
    assert_eq!(map[X::A(PhantomData)], true);
}

#[test]
fn test_sum() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter()
            .map(|(_, v)| v)
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_sum_mut() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter_mut()
            .map(|(_, &mut v)| -> u32 { v })
            .sum::<u32>(),
        32_640
    );
}
<commit_msg>Add a test for iterator cloning<commit_after>#[macro_use]
extern crate enum_map;

use enum_map::{Enum, EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::convert::Infallible;
use std::marker::PhantomData;

trait From<T>: Sized {
    fn from(_: T) -> Self {
        unreachable!();
    }
}

impl<T, U> From<T> for U {}

#[derive(Copy, Clone, Debug, Enum, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn test_clear() {
    let mut map = enum_map! { false => 1, true => 2 };
    map.clear();
    assert_eq!(map[true], 0);
    assert_eq!(map[false], 0);
}

#[test]
fn discriminants() {
    #[derive(Debug, Enum, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(Enum)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn into_iter_len() {
    assert_eq!(enum_map! { Example::A | _ => 0 }.into_iter().len(), 3);
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

#[test]
fn into_iter_u8() {
    assert_eq!(
        <EnumMap<_, _> as core::convert::From<_>>::from(|i: u8| i)
            .into_iter()
            .collect::<Vec<_>>(),
        (0..256).map(|x| (x as u8, x as u8)).collect::<Vec<_>>()
    );
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }
    .into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn values_rev_collect() {
    assert_eq!(
        vec![3, 2, 1],
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .values()
            .rev()
            .cloned()
            .collect::<Vec<_>>()
    );
}

#[test]
fn values_len() {
    assert_eq!(enum_map! { false => 0, true => 1 }.values().len(), 2);
}

#[test]
fn values_mut_next_back() {
    let mut map = enum_map! { false => 0, true => 1 };
    assert_eq!(map.values_mut().next_back(), Some(&mut 1));
}
#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(Enum)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map! {};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[test]
fn empty_infallible_map() {
    let void: EnumMap<Infallible, Infallible> = enum_map! {};
    assert!(void.is_empty());
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Enum<V> for X {
    type Array = [V; 1];
    const POSSIBLE_VALUES: usize = 1;

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
    assert_eq!(map[X::A(PhantomData)], true);
}

#[test]
fn test_sum() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter()
            .map(|(_, v)| v)
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_sum_mut() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter_mut()
            .map(|(_, &mut v)| -> u32 { v })
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_iter_clone() {
    let map = enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 1 };
    let iter = map.iter();
    assert_eq!(iter.clone().map(|(_, v)| v).sum::<u32>(), 8);
    assert_eq!(iter.map(|(_, v)| v).sum::<u32>(), 8);
    let values = map.values();
    assert_eq!(values.clone().sum::<u32>(), 8);
    assert_eq!(values.sum::<u32>(), 8);
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate image;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::rc::Rc;
use std::cell::RefCell;
use opengl_graphics::{ GlGraphics, OpenGL, Texture };
use sdl2_window::Sdl2Window;
use image::GenericImage;
use piston::input::{ Button, MouseButton };
use piston::window::{ WindowSettings, Size };

fn main() {
    let opengl = OpenGL::_3_2;
    let (width, height) = (300, 300);
    let window = Sdl2Window::new(
        opengl,
        WindowSettings::new(
            "piston-example-paint".to_string(),
            Size { width: width, height: height }
        )
        .exit_on_esc(true)
    );

    let mut image = image::ImageBuffer::new(width, height);
    let mut draw = false;
    let mut texture = Texture::from_image(&image);
    let ref mut gl = GlGraphics::new(opengl);
    let window = Rc::new(RefCell::new(window));
    for e in piston::events(window) {
        use piston::event::*;

        if let Some(args) = e.render_args() {
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([1.0; 4], gl);
                graphics::image(&texture, c.transform, gl);
            });
        };
        if let Some(button) = e.press_args() {
            if button == Button::Mouse(MouseButton::Left) {
                draw = true
            }
        };
        if let Some(button) = e.release_args() {
            if button == Button::Mouse(MouseButton::Left) {
                draw = false
            }
        };
        if draw {
            if let Some(pos) = e.mouse_cursor_args() {
                let (x, y) = (pos[0] as u32, pos[1] as u32);
                if x < width && y < height {
                    image.put_pixel(x, y, image::Rgba([0, 0, 0, 255]));
                    texture.update(&image);
                }
            };
        }
    }
}

<commit_msg>Updated "paint" example<commit_after>extern crate piston;
extern crate image;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use opengl_graphics::{ GlGraphics, OpenGL, Texture };
use sdl2_window::Sdl2Window;
use image::GenericImage;
use piston::input::{ Button, MouseButton };
use piston::window::{ WindowSettings, Size };
use piston::event::*;

fn main() {
    let opengl = OpenGL::_3_2;
    let (width, height) = (300, 300);
    let window = Sdl2Window::new(
        opengl,
        WindowSettings::new(
            "piston-example-paint".to_string(),
            Size { width: width, height: height }
        )
        .exit_on_esc(true)
    );

    let mut image = image::ImageBuffer::new(width, height);
    let mut draw = false;
    let mut texture = Texture::from_image(&image);
    let ref mut gl = GlGraphics::new(opengl);
    for e in window.events() {
        use piston::event::*;

        if let Some(args) = e.render_args() {
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([1.0; 4], gl);
                graphics::image(&texture, c.transform, gl);
            });
        };
        if let Some(button) = e.press_args() {
            if button == Button::Mouse(MouseButton::Left) {
                draw = true
            }
        };
        if let Some(button) = e.release_args() {
            if button == Button::Mouse(MouseButton::Left) {
                draw = false
            }
        };
        if draw {
            if let Some(pos) = e.mouse_cursor_args() {
                let (x, y) = (pos[0] as u32, pos[1] as u32);
                if x < width && y < height {
                    image.put_pixel(x, y, image::Rgba([0, 0, 0, 255]));
                    texture.update(&image);
                }
            };
        }
    }
}

<|endoftext|>


<commit_before>use parser::{Expression, CallArgs, Identifier};
use memory::MemoryBlock;

use operations::{Error, OperationsResult};
use operations::item_type::{ItemType, FuncArgType};
use operations::scope::{TypeId, ScopeStack, ScopeItem, FuncArgs};

/// Evaluates the arguments first, then supplies them to the given method
pub fn call_with_exprs(
    scope: &mut ScopeStack,
    method: Expression,
    arg_exprs: CallArgs,
    target_type: TypeId,
    target: MemoryBlock,
) -> OperationsResult {
    let (mut args, ops): (Vec<_>, Vec<_>) = arg_exprs.into_iter().map(|expr| match expr {
        Expression::ByteLiteral(bytes) => Ok((ScopeItem::ByteLiteral(bytes), Vec::new())),
        Expression::Number(bytes) => Ok((ScopeItem::NumericLiteral(bytes), Vec::new())),
        Expression::Identifier(name) => scope.lookup(&name).first().ok_or_else(|| {
            Error::UnresolvedName(name.clone())
        }).map(|item| ((**item).clone(), Vec::new())),
        Expression::Call {..} => unimplemented!(),
        Expression::Access {..} => unimplemented!(),
        Expression::Branch {..} => unimplemented!(),
    }).collect::<Result<Vec<_>, _>>()?.into_iter().unzip();

    let (target_instance, method_name): (Option<ScopeItem>, Identifier) = match method {
        Expression::Identifier(name) => (None, name),
        Expression::Access {target, field} => {
            let (target, method_name) = resolve_field_name(scope, *target, field)?;
            (Some(target), method_name)
        },
        // The grammar should prevent any other expressions from
        // ending up here
        //TODO: Instead of using unreachable here, maybe the type of method should not be expression
        _ => unreachable!(),
    };

    // If the method operates on some type, the instance of that type is the first argument
    if let Some(target_instance) = target_instance {
        args.insert(0, target_instance);
    }

    Ok(ops.into_iter().flat_map(|o| o.into_iter()).chain(
        call(scope, method_name, args, target_type, target)?
    ).collect())
}

/// Call the provided method with the given arguments
pub fn call(
    scope: &mut ScopeStack,
    method_name: Identifier,
    args: FuncArgs,
    target_type: TypeId,
    target: MemoryBlock,
) -> OperationsResult {
    // The first stage of calling a function is finding an implementation that matches the correct
    // function signature.
    let method_args_types = args.iter().map(|arg| match *arg {
        //TODO: Update this when more numeric types are added
        ScopeItem::NumericLiteral(..) => FuncArgType::Arg(scope.primitives().u8()),
        ScopeItem::ByteLiteral(..) => FuncArgType::Array {item: scope.primitives().u8(), size: None},
        ScopeItem::Array {item, ..} => FuncArgType::Array {item: item, size: None},
        ref arg => FuncArgType::Arg(arg.type_id()),
    }).collect();

    // TODO: Since we don't have proper generics, we just search through and try every function
    // with the given name to see if its arguments match. This is more similar to what C++ does
    // than Rust, but it works for the timebeing.
    // We keep searching until we find something that matches or we return the first error.
    scope.lookup(&method_name).into_iter().fold(Err(Error::UnresolvedName(method_name.clone())), |acc, item| acc.or_else(|err| match *item {
        ScopeItem::BuiltInFunction {type_id, ref operations} => {
            if scope.get_type(type_id).matches_signature(&method_args_types, target_type) {
                Ok(operations.clone())
            }
            else {
                Err(err)
            }
        },
        _ => Err(err),
    })).and_then(|operations| (*operations)(scope, args, target))
}

/// Returns the full path of the target type with the field appended to it
/// e.g. If target's type is `std::Foo` and field is `bar`, you get: `std::Foo::bar`
/// Also returns the target ScopeItem of this operation
/// Since this is a field access, it needs to operate on the target object that the `target`
/// expression refers to
fn resolve_field_name(scope: &ScopeStack, target: Expression, field: Identifier) -> Result<(ScopeItem, Identifier), Error> {
    // The full path of the target type
    // Something like `std::foo::Foo` or `u8` or `()`
    let (target_instance, target_type_path) = match target {
        Expression::Identifier(target_name) => scope.lookup(&target_name).first().ok_or_else(|| {
            Error::UnresolvedName(target_name.clone())
        }).and_then(|item| match **item {
            ScopeItem::Constant {type_id, ..} => Ok(((*item).clone(), type_id)),
            ScopeItem::TypedBlock {type_id, ..} => Ok(((*item).clone(), type_id)),
            ScopeItem::Array {..} => unimplemented!(),
            ScopeItem::BuiltInFunction {type_id, ..} => Err(Error::UnresolvedField {
                target_type: scope.get_type(type_id).clone(),
                field: field.clone(),
            }),
            // These are unreachable because numeric literals and byte literals are never stored
            // directly
            ScopeItem::NumericLiteral(..) | ScopeItem::ByteLiteral(..) => unreachable!(),
        }).map(|(item, type_id)| (item, scope.get_type_name(type_id).clone())),

        //TODO: It's likely that the below line will just not work at all
        // because the scope item returned in the tuple is not the target we should return.
        // I think we need to map on this result and return the field as the target...not sure.
        //Expression::Access {target, field} => resolve_field_name(scope, *target, field),
        Expression::Access {target, field} => unimplemented!(),

        //TODO: ByteLiterals are valid targets for field access
        // In this case, we need to return [u8; N] where N is the length of the byte literal
        // We also likely need to allocate and store this into a temporary variable
        Expression::ByteLiteral(..) => unimplemented!(),

        //TODO: Numbers are valid targets for field access
        // In this case, we need to return u8 or another valid type
        // We also likely need to allocate and store this into a temporary variable
        Expression::Number(..) => unimplemented!(),

        //TODO: Calls are valid targets for field access
        // In this case, we need to return the type name of the return type
        // Implementing this will be a bit more complicated since we need to do the call and return
        // the ops necessary for that
        Expression::Call {method, args} => unimplemented!(),
        Expression::Branch {..} => unreachable!(),
    }?;

    Ok((target_instance, target_type_path.concat(field)))
}
<commit_msg>Fixing some warnings<commit_after>use parser::{Expression, CallArgs, Identifier};
use memory::MemoryBlock;

use operations::{Error, OperationsResult};
use operations::item_type::FuncArgType;
use operations::scope::{TypeId, ScopeStack, ScopeItem, FuncArgs};

/// Evaluates the arguments first, then supplies them to the given method
pub fn call_with_exprs(
    scope: &mut ScopeStack,
    method: Expression,
    arg_exprs: CallArgs,
    target_type: TypeId,
    target: MemoryBlock,
) -> OperationsResult {
    let (mut args, ops): (Vec<_>, Vec<_>) = arg_exprs.into_iter().map(|expr| match expr {
        Expression::ByteLiteral(bytes) => Ok((ScopeItem::ByteLiteral(bytes), Vec::new())),
        Expression::Number(bytes) => Ok((ScopeItem::NumericLiteral(bytes), Vec::new())),
        Expression::Identifier(name) => scope.lookup(&name).first().ok_or_else(|| {
            Error::UnresolvedName(name.clone())
        }).map(|item| ((**item).clone(), Vec::new())),
        Expression::Call {..} => unimplemented!(),
        Expression::Access {..} => unimplemented!(),
        Expression::Branch {..} => unimplemented!(),
    }).collect::<Result<Vec<_>, _>>()?.into_iter().unzip();

    let (target_instance, method_name): (Option<ScopeItem>, Identifier) = match method {
        Expression::Identifier(name) => (None, name),
        Expression::Access {target, field} => {
            let (target, method_name) = resolve_field_name(scope, *target, field)?;
            (Some(target), method_name)
        },
        // The grammar should prevent any other expressions from
        // ending up here
        //TODO: Instead of using unreachable here, maybe the type of method should not be expression
        _ => unreachable!(),
    };

    // If the method operates on some type, the instance of that type is the first argument
    if let Some(target_instance) = target_instance {
        args.insert(0, target_instance);
    }

    Ok(ops.into_iter().flat_map(|o| o.into_iter()).chain(
        call(scope, method_name, args, target_type, target)?
    ).collect())
}

/// Call the provided method with the given arguments
pub fn call(
    scope: &mut ScopeStack,
    method_name: Identifier,
    args: FuncArgs,
    target_type: TypeId,
    target: MemoryBlock,
) -> OperationsResult {
    // The first stage of calling a function is finding an implementation that matches the correct
    // function signature.
    let method_args_types = args.iter().map(|arg| match *arg {
        //TODO: Update this when more numeric types are added
        ScopeItem::NumericLiteral(..) => FuncArgType::Arg(scope.primitives().u8()),
        ScopeItem::ByteLiteral(..) => FuncArgType::Array {item: scope.primitives().u8(), size: None},
        ScopeItem::Array {item, ..} => FuncArgType::Array {item: item, size: None},
        ref arg => FuncArgType::Arg(arg.type_id()),
    }).collect();

    // TODO: Since we don't have proper generics, we just search through and try every function
    // with the given name to see if its arguments match. This is more similar to what C++ does
    // than Rust, but it works for the timebeing.
    // We keep searching until we find something that matches or we return the first error.
    scope.lookup(&method_name).into_iter().fold(Err(Error::UnresolvedName(method_name.clone())), |acc, item| acc.or_else(|err| match *item {
        ScopeItem::BuiltInFunction {type_id, ref operations} => {
            if scope.get_type(type_id).matches_signature(&method_args_types, target_type) {
                Ok(operations.clone())
            }
            else {
                Err(err)
            }
        },
        _ => Err(err),
    })).and_then(|operations| (*operations)(scope, args, target))
}

/// Returns the full path of the target type with the field appended to it
/// e.g. If target's type is `std::Foo` and field is `bar`, you get: `std::Foo::bar`
/// Also returns the target ScopeItem of this operation
/// Since this is a field access, it needs to operate on the target object that the `target`
/// expression refers to
fn resolve_field_name(scope: &ScopeStack, target: Expression, field: Identifier) -> Result<(ScopeItem, Identifier), Error> {
    // The full path of the target type
    // Something like `std::foo::Foo` or `u8` or `()`
    let (target_instance, target_type_path) = match target {
        Expression::Identifier(target_name) => scope.lookup(&target_name).first().ok_or_else(|| {
            Error::UnresolvedName(target_name.clone())
        }).and_then(|item| match **item {
            ScopeItem::Constant {type_id, ..} => Ok(((*item).clone(), type_id)),
            ScopeItem::TypedBlock {type_id, ..} => Ok(((*item).clone(), type_id)),
            ScopeItem::Array {..} => unimplemented!(),
            ScopeItem::BuiltInFunction {type_id, ..} => Err(Error::UnresolvedField {
                target_type: scope.get_type(type_id).clone(),
                field: field.clone(),
            }),
            // These are unreachable because numeric literals and byte literals are never stored
            // directly
            ScopeItem::NumericLiteral(..) | ScopeItem::ByteLiteral(..) => unreachable!(),
        }).map(|(item, type_id)| (item, scope.get_type_name(type_id).clone())),

        //TODO: It's likely that the below line will just not work at all
        // because the scope item returned in the tuple is not the target we should return.
        // I think we need to map on this result and return the field as the target...not sure.
        //Expression::Access {target, field} => resolve_field_name(scope, *target, field),
        Expression::Access {..} => unimplemented!(),

        //TODO: ByteLiterals are valid targets for field access
        // In this case, we need to return [u8; N] where N is the length of the byte literal
        // We also likely need to allocate and store this into a temporary variable
        Expression::ByteLiteral(..) => unimplemented!(),

        //TODO: Numbers are valid targets for field access
        // In this case, we need to return u8 or another valid type
        // We also likely need to allocate and store this into a temporary variable
        Expression::Number(..) => unimplemented!(),

        //TODO: Calls are valid targets for field access
        // In this case, we need to return the type name of the return type
        // Implementing this will be a bit more complicated since we need to do the call and return
        // the ops necessary for that
        Expression::Call {..} => unimplemented!(),
        Expression::Branch {..} => unreachable!(),
    }?;

    Ok((target_instance, target_type_path.concat(field)))
}
<|endoftext|>