Skip to content

Add ARC::get method and a simple example #6622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
18bf884
Use assert_eq! rather than assert! where possible
May 19, 2013
20033c9
Typo corrected and updated copyright years
May 19, 2013
efd965c
Add the get method to std::arc::ARC
May 19, 2013
f0f4d2d
Implement the get function on ARC from the method
May 19, 2013
e0b1bdc
Add additional documentation in core::io.
steveklabnik May 19, 2013
a389d86
Add docs for stdin in core::io.
steveklabnik May 19, 2013
929050d
Added note about prelude inclusion.
steveklabnik May 19, 2013
507ca42
Add an example
May 19, 2013
99a1704
Typos in the example
May 19, 2013
ebdb0de
auto merge of #6620 : steveklabnik/rust/stdin_docs, r=brson
bors May 19, 2013
5877727
Fix trailing whitespace
steveklabnik May 19, 2013
e02716e
Reexport static trait methods on traits in the same module.
thomaslee May 12, 2013
cac97d7
Remove unused variable.
thomaslee May 12, 2013
e3a91f6
Explain an odd conditional check.
thomaslee May 19, 2013
7396f7f
auto merge of #6432 : thomaslee/rust/issue-4202-02, r=catamorphism
bors May 20, 2013
9283dfe
auto merge of #6619 : steveklabnik/rust/stdout_docs, r=thestinger
bors May 20, 2013
b1e8056
Add a better introduction for the io module.
steveklabnik May 20, 2013
e42fcb9
Implement unimplemented const binops
emberian May 19, 2013
b976427
Fix LLVMConst{I,F}Cmp
emberian May 20, 2013
808c5b8
Test fixes, use LLVMConstFCmp in ConstFCmp
emberian May 20, 2013
91d3e7f
Fix wording per feedback
steveklabnik May 20, 2013
cab9249
auto merge of #6625 : cmr/rust/constops, r=Aatch
bors May 20, 2013
0b39bc2
auto merge of #6624 : steveklabnik/rust/io_prelude, r=catamorphism
bors May 20, 2013
3a481c0
auto merge of #6627 : steveklabnik/rust/remove_warnings, r=thestinger…
bors May 20, 2013
e89bec3
Rebase
May 20, 2013
b704072
Typo corrected and updated copyright years
May 19, 2013
7bb89e9
Add the get method to std::arc::ARC
May 19, 2013
8c34414
Implement the get function on ARC from the method
May 19, 2013
4ca089e
Add an example
May 19, 2013
dfb9c53
Typos in the example
May 19, 2013
f56eb75
Merge branch 'arc' of github.com:osaut/rust into arc
May 20, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 85 additions & 1 deletion src/libcore/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,37 @@

/*!

Basic input/output
The `io` module contains basic input and output routines.

A quick summary:

## `Reader` and `Writer` traits

These traits define the minimal set of methods that anything that can do
input and output should implement.

## `ReaderUtil` and `WriterUtil` traits

Richer methods that allow you to do more. `Reader` only lets you read a certain
number of bytes into a buffer, while `ReaderUtil` allows you to read a whole
line, for example.

Generally, these richer methods are probably the ones you want to actually
use in day-to-day Rust.

Furthermore, because there is an implementation of `ReaderUtil` for
`<T: Reader>`, when your input or output code implements `Reader`, you get
all of these methods for free.

## `print` and `println`

These very useful functions are defined here. You generally don't need to
import them, though, as the prelude already does.

## `stdin`, `stdout`, and `stderr`

These functions return references to the classic three file descriptors. They
implement `Reader` and `Writer`, where appropriate.

*/

Expand Down Expand Up @@ -1010,6 +1040,16 @@ pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
// top-level functions that take a reader, or a set of default methods on
// reader (which can then be called reader)

/**
* Gives a `Reader` that allows you to read values from standard input.
*
* # Examples
* ~~~
* let stdin = core::io::stdin();
* let line = stdin.read_line();
* core::io::print(line);
* ~~~
*/
pub fn stdin() -> @Reader {
unsafe {
@rustrt::rust_get_stdin() as @Reader
Expand Down Expand Up @@ -1561,13 +1601,57 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
// FIXME (#2004) it would be great if this could be a const
// FIXME (#2004) why are these different from the way stdin() is
// implemented?


/**
* Gives a `Writer` which allows you to write to the standard output.
*
* # Examples
* ~~~
* let stdout = core::io::stdout();
* stdout.write_str("hello\n");
* ~~~
*/
pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }

/**
* Gives a `Writer` which allows you to write to standard error.
*
* # Examples
* ~~~
* let stderr = core::io::stderr();
* stderr.write_str("hello\n");
* ~~~
*/
pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }

/**
* Prints a string to standard output.
*
* This string will not have an implicit newline at the end. If you want
* an implicit newline, please see `println`.
*
* # Examples
* ~~~
* // print is imported into the prelude, and so is always available.
* print("hello");
* ~~~
*/
pub fn print(s: &str) {
stdout().write_str(s);
}

/**
* Prints a string to standard output, followed by a newline.
*
* If you do not want an implicit newline, please see `print`.
*
* # Examples
* ~~~
* // println is imported into the prelude, and so is always available.
* println("hello");
* ~~~
*/
pub fn println(s: &str) {
stdout().write_line(s);
}
Expand Down
18 changes: 16 additions & 2 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

use core::hashmap::HashMap;
use core::libc::c_uint;
use core::libc::{c_uint, c_ushort};

pub type Opcode = u32;
pub type Bool = c_uint;
Expand Down Expand Up @@ -221,7 +221,7 @@ pub mod llvm {
use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
use super::{ValueRef};

use core::libc::{c_char, c_int, c_longlong, c_uint, c_ulonglong};
use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong};

#[link_args = "-Lrustllvm -lrustllvm"]
#[link_name = "rustllvm"]
Expand Down Expand Up @@ -451,6 +451,10 @@ pub mod llvm {
/* all zeroes */
#[fast_ffi]
pub unsafe fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) -> ValueRef;
/* only for int/vector */
#[fast_ffi]
pub unsafe fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
Expand Down Expand Up @@ -1914,6 +1918,16 @@ pub fn SetLinkage(Global: ValueRef, Link: Linkage) {
}
}

pub fn ConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
unsafe {
llvm::LLVMConstICmp(Pred as c_ushort, V1, V2)
}
}
pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
unsafe {
llvm::LLVMConstFCmp(Pred as c_ushort, V1, V2)
}
}
/* Memory-managed object interface to type handles. */

pub struct TypeNames {
Expand Down
16 changes: 14 additions & 2 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,20 @@ fn encode_reexported_static_methods(ecx: @EncodeContext,
match ecx.tcx.trait_methods_cache.find(&exp.def_id) {
Some(methods) => {
match ecx.tcx.items.find(&exp.def_id.node) {
Some(&ast_map::node_item(_, path)) => {
if mod_path != *path {
Some(&ast_map::node_item(item, path)) => {
let original_name = ecx.tcx.sess.str_of(item.ident);

//
// We don't need to reexport static methods on traits
// declared in the same module as our `pub use ...` since
// that's done when we encode the trait item.
//
// The only exception is when the reexport *changes* the
// name e.g. `pub use Foo = self::Bar` -- we have
// encoded metadata for static methods relative to Bar,
// but not yet for Foo.
//
if mod_path != *path || *exp.name != *original_name {
for methods.each |&m| {
if m.explicit_self == ast::sty_static {
encode_reexported_static_method(ecx,
Expand Down
57 changes: 45 additions & 12 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
// except according to those terms.

use back::abi;
use lib::llvm::{llvm, SetLinkage, PrivateLinkage,
ValueRef, TypeRef, Bool, True, False};
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool,
True, False};
use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};

use metadata::csearch;
use middle::const_eval;
use middle::trans::adt;
Expand Down Expand Up @@ -280,8 +283,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
else if signed { llvm::LLVMConstSRem(te1, te2) }
else { llvm::LLVMConstURem(te1, te2) }
}
ast::and |
ast::or => cx.sess.span_unimpl(e.span, "binop logic"),
ast::and => llvm::LLVMConstAnd(te1, te2),
ast::or => llvm::LLVMConstOr(te1, te2),
ast::bitxor => llvm::LLVMConstXor(te1, te2),
ast::bitand => llvm::LLVMConstAnd(te1, te2),
ast::bitor => llvm::LLVMConstOr(te1, te2),
Expand All @@ -290,14 +293,44 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
}
ast::eq |
ast::lt |
ast::le |
ast::ne |
ast::ge |
ast::gt => cx.sess.span_unimpl(e.span, "binop comparator")
}
}
ast::eq => {
if is_float { ConstFCmp(RealOEQ, te1, te2) }
else { ConstICmp(IntEQ, te1, te2) }
},
ast::lt => {
if is_float { ConstFCmp(RealOLT, te1, te2) }
else {
if signed { ConstICmp(IntSLT, te1, te2) }
else { ConstICmp(IntULT, te1, te2) }
}
},
ast::le => {
if is_float { ConstFCmp(RealOLE, te1, te2) }
else {
if signed { ConstICmp(IntSLE, te1, te2) }
else { ConstICmp(IntULE, te1, te2) }
}
},
ast::ne => {
if is_float { ConstFCmp(RealONE, te1, te2) }
else { ConstICmp(IntNE, te1, te2) }
},
ast::ge => {
if is_float { ConstFCmp(RealOGE, te1, te2) }
else {
if signed { ConstICmp(IntSGE, te1, te2) }
else { ConstICmp(IntUGE, te1, te2) }
}
},
ast::gt => {
if is_float { ConstFCmp(RealOGT, te1, te2) }
else {
if signed { ConstICmp(IntSGT, te1, te2) }
else { ConstICmp(IntUGT, te1, te2) }
}
},
};
},
ast::expr_unary(u, e) => {
let te = const_expr(cx, e);
let ty = ty::expr_ty(cx.tcx, e);
Expand Down
40 changes: 35 additions & 5 deletions src/libstd/arc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -8,9 +8,33 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/**
/*!
* Concurrency-enabled mechanisms for sharing mutable and/or immutable state
* between tasks.
*
* # Example
*
* In this example, a large vector of floats is shared between several tasks.
* With simple pipes, without ARC, a copy would have to be made for each task.
*
* ~~~
* extern mod std;
* use std::arc;
* let numbers=vec::from_fn(100, |ind| (ind as float)*rand::random());
* let shared_numbers=arc::ARC(numbers);
*
* for 10.times {
* let (port, chan) = stream();
* chan.send(shared_numbers.clone());
*
* do spawn {
* let shared_numbers=port.recv();
* let local_numbers=shared_numbers.get();
*
* // Work with the local numbers
* }
* }
* ~~~
*/

use sync;
Expand All @@ -21,7 +45,7 @@ use core::unstable::sync::UnsafeAtomicRcBox;
use core::ptr;
use core::task;

/// As sync::condvar, a mechanism for unlock-and-descheduling and signalling.
/// As sync::condvar, a mechanism for unlock-and-descheduling and signaling.
pub struct Condvar<'self> {
is_mutex: bool,
failed: &'self mut bool,
Expand Down Expand Up @@ -93,9 +117,14 @@ pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
* wrapper.
*/
pub fn get<'a, T:Const + Owned>(rc: &'a ARC<T>) -> &'a T {
unsafe { &*rc.x.get_immut() }
rc.get()
}

impl<T:Const+Owned> ARC<T> {
pub fn get<'a>(&'a self) -> &'a T {
unsafe { &*self.x.get_immut() }
}
}
/**
* Duplicate an atomically reference counted wrapper.
*
Expand Down Expand Up @@ -501,13 +530,14 @@ mod tests {
let arc_v = p.recv();

let v = copy *arc::get::<~[int]>(&arc_v);
assert_eq!(v[3], 4);
assert_eq!(v[3],4);
};

let c = p.recv();
c.send(arc::clone(&arc_v));

assert_eq!((*arc::get(&arc_v))[2], 3);
assert_eq!(arc_v.get()[4], 5);

info!(arc_v);
}
Expand Down
10 changes: 10 additions & 0 deletions src/test/auxiliary/mod_trait_with_static_methods_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
// except according to those terms.

pub use sub_foo::Foo;
pub use Baz = self::Bar;

pub trait Bar {
pub fn bar() -> Self;
}

impl Bar for int {
pub fn bar() -> int { 84 }
}

pub mod sub_foo {
pub trait Foo {
Expand All @@ -18,4 +27,5 @@ pub mod sub_foo {
impl Foo for int {
pub fn foo() -> int { 42 }
}

}
Loading