<commit_before>use syntax::lexer::Tokenizer;
use syntax::core::tokens::Token;
use syntax::core::tokens::Token::*;
use syntax::core::keywords::Keywords;
use syntax::core::symbols::Symbols;
use syntax::ast::expr::*;

pub struct Parser<TokType: Tokenizer> {
    lexer: TokType,
    indentation: usize,
    run_codegen: bool,
    ast_root: ExprWrapper
}

impl<TokType: Tokenizer> Parser<TokType> {
    pub fn new(tokenizer: TokType) -> Parser<TokType> {
        let expr = Box::new(Expr::BlockExpr(Vec::new()));
        let wrapper = ExprWrapper::new(expr, 0, 0, 0, 0);

        Parser {
            lexer: tokenizer,
            indentation: 0,
            run_codegen: true,
            ast_root: wrapper
        }
    }

    // Get the next token from the lexer
    fn next_token(&mut self) -> Token {
        self.lexer.get_tok()
    }

    // Create an error from the current lexer's
    // state, and a message
    fn write_error(&mut self, msg: &str) {
        let (start_line, start_column, _, _) = self.lexer.get_error_pos();

        self.run_codegen = false;

        println!("Error on line: {} col: {}, {}", start_line, start_column, msg);

        // Skip to the end of the line (at Indent token) and allow parsing to continue
        loop {
            // Note: This consumes the Indent token, which probably isnt ideal.
            match self.next_token() {
                Indent(_) => break,
                EOF => break,
                _ => ()
            }
        }
    }

    fn expect_error(&mut self, reason: &str, expect: &str, got: &str) {
        self.write_error(&format!("{}. Expected {}, but got {}", reason, expect, got));
    }

    // Perform any necessary on-start actions
    fn start(&self) {
        // Start code gen startup

        // Implicit imports

        // Generate code for implicit top level function definition
    }

    // Ensures that the indentation matches the current level of indentation
    #[allow(dead_code)]
    fn check_indentation(&mut self, depth: usize) -> Option<ExprWrapper> {
        if self.indentation == depth {
            return None;
        }

        self.write_error("Incorrect indentation level");

        None
    }

    // Parses a variable or constant declaration
    #[allow(unused_variables)]
    #[allow(dead_code)]
    fn parse_declaration(&mut self) -> Option<ExprWrapper> {
        let token = self.next_token();
        match token {
            Identifier(name) => {
                let token1 = self.next_token();

                match token1 {
                    // Symbol(punc) => {
                    //     match punc {
                    //         symbols::Assign => {
                    //             self.parse_expression()
                    //         }
                    //         _ => Err(self.write_error("Invalid Symbol here"))
                    //     }
                    // }
                    Symbol(Symbols::Equals) => {
                        return self.parse_expression();
                    },
                    _ => self.write_error("Invalid sequence")
                }
            },
            Error(msg) => self.write_error(&msg),
            _ => self.expect_error("", "a variable name", "something else")
        }

        None
    }

    fn expect_token(&self, token: &Token, next_token: Token) -> bool {
        if *token == next_token {
            return true;
        }
        return false;
    }

    fn collect_args(&mut self) -> Option<Vec<ExprWrapper>> {
        let mut args = Vec::new();
        let mut seen_one_arg = false;
        println!("Before While");
        loop {
            let tok = self.next_token();
            if self.expect_token(&tok, Symbol(Symbols::ParenClose)) {
                println!("hit the close paren {:?}, which is {:?}", tok, Symbol(Symbols::ParenClose));
                return Some(args);
            }
            println!("passed the close paren");

            let name = match tok {
                Token::Identifier(ref name) => Some(name),
                _ => {
                    self.write_error(&format!("Unsupported keyword {:?}.", tok));
                    None
                }
            };
            if let Some(arg) = name {
                println!("hit the ident: {}", arg);
                args.push(ExprWrapper::new_default(
                    Box::new(Expr::IdentExpr(String::from_str(arg)))));
                let tok = self.next_token();
                if self.expect_token(&tok, Symbol(Symbols::Comma)) {
                    println!("hit the comma!");
                    if !seen_one_arg {
                        self.write_error(&format!("Invalid syntax."));
                        return None;
                    }
                    seen_one_arg = true;
                    continue;
                }
            } else {
                return None;
            }
        }
    }

    // Parses a print function/statement
    fn parse_print_fn(&mut self) -> Option<ExprWrapper> {
        let tok = self.next_token();
        if !self.expect_token(&tok, Symbol(Symbols::ParenOpen)) {
            return None;
        }

        println!("Before Collect");
        // let args = self.collect_args();
        self.collect_args();
        return None;
        // Return the ast of the print function
    }

    // Handles top-level keywords to start parsing them
    fn handle_keywords(&mut self, keyword: Keywords) -> Option<ExprWrapper> {
        match keyword {
//            Keywords::Def => {
//                self.parse_declaration()
//            },
            Keywords::Print => {
                self.parse_print_fn()
            },
            _ => {
                self.write_error(&format!("Unsupported keyword {:?}.", keyword));
                None
            }
        }
    }

    #[allow(dead_code)]
    fn parse_expression(&self) -> Option<ExprWrapper> {
        None
    }

    // Parse numbers into their correct representation
    #[allow(unused_variables)]
    #[allow(dead_code)]
    fn parse_number(&mut self, num: &str) -> Option<ExprWrapper> {
        println!("{}", num);
        let value = 0;
        // This would normally check the ending on the thing slash information
        // about the number to pick int, uint, or float
        None
    }

    // Parse the file
    #[allow(unused_variables)]
    pub fn parse(&mut self) {
        self.start();

        // Generate AST
        loop {
            // Parse the token into the next node of the AST
            let token = self.next_token();

            // Debug:
            println!("{:?}", token);

            match token {
                Numeric(string, type_) => {
                    panic!("Unimplemented top level token 'Numeric'");
                },
                Identifier(repr) => {
//                    self.parse_expression()
                    panic!("Unimplemented top level token 'Identifier'");
                },
                Indent(depth) => {
                    // ToDo: Keep track of indentation level when preceeding a statement
                    // Might need look ahead to see if next token is Comment or Indent
                    // which means you didn't actually dedent.
                },
                BoolLiteral(lit) => {
                    panic!("Unimplemented top level token 'BoolLiteral'");
                },
                CharLiteral(lit) => {
                    panic!("Unimplemented top level token 'CharLiteral'");
                },
                StrLiteral(lit) => {
                    panic!("Unimplemented top level token 'StrLiteral'");
                },
                Keyword(keyword) => {
                    if let Some(exprwrapper) = self.handle_keywords(keyword) {
                        if let &mut Expr::BlockExpr(ref mut vec) = self.ast_root.get_expr() {
                            vec.push(exprwrapper);
                        }
                    }
                },
                Symbol(punc) => {
                    panic!("Unimplemented top level token 'Symbol'");
                },
                Comment(text) => {
                    // ToDo: Docstring, else ignore
                },
                Error(err) => {
                    self.write_error(&err);
                },
                Type(type_) => {
                    panic!("Unimplemented top level token 'Type'");
                },
                EOF => break
            };
        }

        // Do semantic analysis on AST

        // Run codegen when no errors have been found
        if self.run_codegen {
            self.ast_root.gen_code();
        }
    }
}
<commit_msg>Started working on parsion function declarations.<commit_after>use syntax::lexer::Tokenizer;
use syntax::core::tokens::Token;
use syntax::core::tokens::Token::*;
use syntax::core::keywords::Keywords;
use syntax::core::symbols::Symbols;
use syntax::ast::expr::*;

pub struct Parser<TokType: Tokenizer> {
    lexer: TokType,
    indentation: usize,
    run_codegen: bool,
    ast_root: ExprWrapper
}

impl<TokType: Tokenizer> Parser<TokType> {
    pub fn new(tokenizer: TokType) -> Parser<TokType> {
        let expr = Box::new(Expr::BlockExpr(Vec::new()));
        let wrapper = ExprWrapper::new(expr, 0, 0, 0, 0);

        Parser {
            lexer: tokenizer,
            indentation: 0,
            run_codegen: true,
            ast_root: wrapper
        }
    }

    // Get the next token from the lexer
    fn next_token(&mut self) -> Token {
        self.lexer.get_tok()
    }

    // Create an error from the current lexer's
    // state, and a message
    fn write_error(&mut self, msg: &str) {
        let (start_line, start_column, _, _) = self.lexer.get_error_pos();

        self.run_codegen = false;

        println!("Error on line: {} col: {}, {}", start_line, start_column, msg);

        // Skip to the end of the line (at Indent token) and allow parsing to continue
        loop {
            // Note: This consumes the Indent token, which probably isnt ideal.
            match self.next_token() {
                Indent(_) => break,
                EOF => break,
                _ => ()
            }
        }
    }

    fn expect_error(&mut self, reason: &str, expect: &str, got: &str) {
        self.write_error(&format!("{}. Expected {}, but got {}", reason, expect, got));
    }

    // Perform any necessary on-start actions
    fn start(&self) {
        // Start code gen startup

        // Implicit imports

        // Generate code for implicit top level function definition
    }

    // Ensures that the indentation matches the current level of indentation
    #[allow(dead_code)]
    fn check_indentation(&mut self, depth: usize) -> Option<ExprWrapper> {
        if self.indentation == depth {
            return None;
        }

        self.write_error("Incorrect indentation level");

        None
    }

    // Parses a variable or constant declaration
    #[allow(unused_variables)]
    #[allow(dead_code)]
    fn parse_declaration(&mut self) -> Option<ExprWrapper> {
        let token = self.next_token();
        match token {
            Identifier(name) => {
                let token1 = self.next_token();

                match token1 {
                    // Symbol(punc) => {
                    //     match punc {
                    //         symbols::Assign => {
                    //             self.parse_expression()
                    //         }
                    //         _ => Err(self.write_error("Invalid Symbol here"))
                    //     }
                    // }
                    Symbol(Symbols::Equals) => {
                        return self.parse_expression();
                    },
                    _ => self.write_error("Invalid sequence")
                }
            },
            Error(msg) => self.write_error(&msg),
            _ => self.expect_error("", "a variable name", "something else")
        }

        None
    }

    fn expect_token(&self, token: &Token, next_token: Token) -> bool {
        if *token == next_token {
            return true;
        }
        return false;
    }

    fn collect_args(&mut self) -> Option<Vec<ExprWrapper>> {
        let mut args = Vec::new();
        let mut seen_one_arg = false;
        println!("Before While");
        loop {
            let tok = self.next_token();
            if self.expect_token(&tok, Symbol(Symbols::ParenClose)) {
                println!("hit the close paren {:?}, which is {:?}", tok, Symbol(Symbols::ParenClose));
                return Some(args);
            }
            println!("passed the close paren");

            let name = match tok {
                Token::Identifier(ref name) => Some(name),
                _ => {
                    self.write_error(&format!("Unsupported keyword {:?}.", tok));
                    None
                }
            };
            if let Some(arg) = name {
                println!("hit the ident: {}", arg);
                args.push(ExprWrapper::new_default(
                    Box::new(Expr::IdentExpr(String::from_str(arg)))));
                let tok = self.next_token();
                if self.expect_token(&tok, Symbol(Symbols::Comma)) {
                    println!("hit the comma!");
                    if !seen_one_arg {
                        self.write_error(&format!("Invalid syntax."));
                        return None;
                    }
                    seen_one_arg = true;
                    continue;
                }
            } else {
                return None;
            }
        }
    }

    // Parses a print function/statement
    fn parse_print_fn(&mut self) -> Option<ExprWrapper> {
        let tok = self.next_token();
        if !self.expect_token(&tok, Symbol(Symbols::ParenOpen)) {
            return None;
        }

        println!("Before Collect");
        // let args = self.collect_args();
        self.collect_args();
        return None;
        // Return the ast of the print function
    }

    // Parse function definitions: fn ident(args) -> type
    fn parse_fn(&mut self) -> Option<ExprWrapper> {
        let fn_name = match self.next_token() {
            Identifier(string) => string,
            _ => return None
        };

        let tok = self.next_token();
        if !self.expect_token(&tok, Symbol(Symbols::ParenOpen)) {
            self.expect_error("", "an opening paren '('", "something else");

            return None;
        }

        return None;
    }

    // Handles top-level keywords to start parsing them
    fn handle_keywords(&mut self, keyword: Keywords) -> Option<ExprWrapper> {
        match keyword {
//            Keywords::Def => {
//                self.parse_declaration()
//            },
            Keywords::Fn => self.parse_fn(),
            Keywords::Print => {
                self.parse_print_fn()
            },
            _ => {
                self.write_error(&format!("Unsupported keyword {:?}.", keyword));
                None
            }
        }
    }

    #[allow(dead_code)]
    fn parse_expression(&self) -> Option<ExprWrapper> {
        None
    }

    // Parse numbers into their correct representation
    #[allow(unused_variables)]
    #[allow(dead_code)]
    fn parse_number(&mut self, num: &str) -> Option<ExprWrapper> {
        println!("{}", num);
        let value = 0;
        // This would normally check the ending on the thing slash information
        // about the number to pick int, uint, or float
        None
    }

    // Parse the file
    #[allow(unused_variables)]
    pub fn parse(&mut self) {
        self.start();

        // Generate AST
        loop {
            // Parse the token into the next node of the AST
            let token = self.next_token();

            // Debug:
            println!("{:?}", token);

            match token {
                Numeric(string, type_) => {
                    panic!("Unimplemented top level token 'Numeric'");
                },
                Identifier(repr) => {
//                    self.parse_expression()
                    panic!("Unimplemented top level token 'Identifier'");
                },
                Indent(depth) => {
                    // ToDo: Keep track of indentation level when preceeding a statement
                    // Might need look ahead to see if next token is Comment or Indent
                    // which means you didn't actually dedent.
                },
                BoolLiteral(lit) => {
                    panic!("Unimplemented top level token 'BoolLiteral'");
                },
                CharLiteral(lit) => {
                    panic!("Unimplemented top level token 'CharLiteral'");
                },
                StrLiteral(lit) => {
                    panic!("Unimplemented top level token 'StrLiteral'");
                },
                Keyword(keyword) => {
                    if let Some(exprwrapper) = self.handle_keywords(keyword) {
                        if let &mut Expr::BlockExpr(ref mut vec) = self.ast_root.get_expr() {
                            vec.push(exprwrapper);
                        }
                    }
                },
                Symbol(punc) => {
                    panic!("Unimplemented top level token 'Symbol'");
                },
                Comment(text) => {
                    // ToDo: Docstring, else ignore
                },
                Error(err) => {
                    self.write_error(&err);
                },
                Type(type_) => {
                    panic!("Unimplemented top level token 'Type'");
                },
                EOF => break
            };
        }

        // Do semantic analysis on AST

        // Run codegen when no errors have been found
        if self.run_codegen {
            self.ast_root.gen_code();
        }
    }
}
<|endoftext|>


<commit_before>//! Importers for RAW volume files. A raw volume file is the raw bytes of
//! volume data in little endian, with X increasing first, then Y, then Z.

use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::mem;
use std::iter;

use num::{self, NumCast};

use vol::Volume;
use vec3::Vec3i;

/// Import a RAW volume file with the set dimensions. The volume data is
/// expected to be of type T which should be a primitive scalar type
pub fn import<T: NumCast>(path: &Path, dims: Vec3i) -> Volume {
    let mut f = match File::open(&path) {
        Ok(f) => BufReader::new(f),
        Err(e) => panic!("Error opening volume {}", e),
    };
    let mut data: Vec<_> = iter::repeat(0u8).take((dims.x * dims.y * dims.z) as usize).collect();
    f.read_exact(&mut data[..]).expect("Failed to read entire RAW volume");
    let data: Vec<f32> = data.chunks(mem::size_of::<T>())
        .map(|x| unsafe { mem::transmute_copy::<u8, T>(&x[0]) })
        .map(|x| num::cast(x).unwrap()).collect();
    let mut volume = Volume::new(dims);
    volume.set_region(&data[..], Vec3i::broadcast(0), dims);
    volume
}

<commit_msg>Fix amount of space we allocate for non-1 byte types<commit_after>//! Importers for RAW volume files. A raw volume file is the raw bytes of
//! volume data in little endian, with X increasing first, then Y, then Z.

use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::mem;
use std::iter;

use num::{self, NumCast};

use vol::Volume;
use vec3::Vec3i;

/// Import a RAW volume file with the set dimensions. The volume data is
/// expected to be of type T which should be a primitive scalar type
pub fn import<T: NumCast>(path: &Path, dims: Vec3i) -> Volume {
    let mut f = match File::open(&path) {
        Ok(f) => BufReader::new(f),
        Err(e) => panic!("Error opening volume {}", e),
    };
    let mut data: Vec<_> = iter::repeat(0u8)
        .take((dims.x * dims.y * dims.z) as usize * mem::size_of::<T>()).collect();
    f.read_exact(&mut data[..]).expect("Failed to read entire RAW volume");
    let data: Vec<f32> = data.chunks(mem::size_of::<T>())
        .map(|x| unsafe { mem::transmute_copy::<u8, T>(&x[0]) })
        .map(|x| num::cast(x).unwrap()).collect();
    let mut volume = Volume::new(dims);
    volume.set_region(&data[..], Vec3i::broadcast(0), dims);
    volume
}

<|endoftext|>


<commit_before>#[allow(unused_imports)]
use tensor::Tensor;

#[test]
fn matrix_matrix_1() {
    // Test square matrices
    let t1 = Tensor::new(vec![ 0.0, 3.0, 2.0, 10.0]).reshaped(&[2, 2]);
    let t2 = Tensor::new(vec![-2.0, 1.0, 8.0,  0.0]).reshaped(&[2, 2]);
    let answer = Tensor::new(vec![24.0, 0.0, 76.0, 2.0]).reshaped(&[2, 2]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", Tensor::dot(&t1, &t2));
    assert!(Tensor::dot(&t1, &t2) == answer);
}

#[test]
fn matrix_matrix_2() {
    let t1 = Tensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]).reshaped(&[3, 2]);
    let t2 = Tensor::new(vec![-2.0, 1.0, 8.0,  0.0]).reshaped(&[2, 2]);
    let answer = Tensor::new(vec![24.0, 0.0, 76.0, 2.0, 6.0, -3.0]).reshaped(&[3, 2]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", Tensor::dot(&t1, &t2));
    assert!(Tensor::dot(&t1, &t2) == answer);
}

#[test]
fn matrix_vector_1() {
    let t1 = Tensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]).reshaped(&[3, 2]);
    //let t1 = Tensor::new(vec![ 0.0, 2.0, -3.0, 3.0, 10.0, 0.0]).reshaped(&[3, 2]);
    let t2 = Tensor::new(vec![-2.0, 1.0]);
    let answer = Tensor::new(vec![3.0, 6.0, 6.0]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", Tensor::dot(&t1, &t2));
    assert!(Tensor::dot(&t1, &t2) == answer);
}

#[test]
fn vector_vector_1() {
    let t1 = Tensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]);
    let t2 = Tensor::new(vec![-2.0, 1.0, 3.0, -2.0, -3.0, 1.0]);
    let answer = Tensor::new(vec![-2.0]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", Tensor::dot(&t1, &t2));
    assert!(Tensor::dot(&t1, &t2) == answer);
}
<commit_msg>Fixed dot tastes to be f64 specific<commit_after>#[allow(unused_imports)]
use tensor::DoubleTensor;

#[test]
fn matrix_matrix_1() {
    // Test square matrices
    let t1 = DoubleTensor::new(vec![ 0.0, 3.0, 2.0, 10.0]).reshaped(&[2, 2]);
    let t2 = DoubleTensor::new(vec![-2.0, 1.0, 8.0,  0.0]).reshaped(&[2, 2]);
    let answer = DoubleTensor::new(vec![24.0, 0.0, 76.0, 2.0]).reshaped(&[2, 2]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", DoubleTensor::dot(&t1, &t2));
    assert!(DoubleTensor::dot(&t1, &t2) == answer);
}

#[test]
fn matrix_matrix_2() {
    let t1 = DoubleTensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]).reshaped(&[3, 2]);
    let t2 = DoubleTensor::new(vec![-2.0, 1.0, 8.0,  0.0]).reshaped(&[2, 2]);
    let answer = DoubleTensor::new(vec![24.0, 0.0, 76.0, 2.0, 6.0, -3.0]).reshaped(&[3, 2]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", DoubleTensor::dot(&t1, &t2));
    assert!(DoubleTensor::dot(&t1, &t2) == answer);
}

#[test]
fn matrix_vector_1() {
    let t1 = DoubleTensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]).reshaped(&[3, 2]);
    //let t1 = DoubleTensor::new(vec![ 0.0, 2.0, -3.0, 3.0, 10.0, 0.0]).reshaped(&[3, 2]);
    let t2 = DoubleTensor::new(vec![-2.0, 1.0]);
    let answer = DoubleTensor::new(vec![3.0, 6.0, 6.0]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", DoubleTensor::dot(&t1, &t2));
    assert!(DoubleTensor::dot(&t1, &t2) == answer);
}

#[test]
fn vector_vector_1() {
    let t1 = DoubleTensor::new(vec![ 0.0, 3.0, 2.0, 10.0, -3.0, 0.0]);
    let t2 = DoubleTensor::new(vec![-2.0, 1.0, 3.0, -2.0, -3.0, 1.0]);
    let answer = DoubleTensor::new(vec![-2.0]);

    println!("t1 = \n{}", t1);
    println!("t2 = \n{}", t2);
    println!("answer = \n{}", DoubleTensor::dot(&t1, &t2));
    assert!(DoubleTensor::dot(&t1, &t2) == answer);
}
<|endoftext|>


<commit_before>use super::Color;
use enum_map::{enum_map, Enum, EnumMap};
use log::warn;
use toml;

use hashbrown::HashMap;
use std::ops::{Index, IndexMut};

/// Color configuration for the application.
///
/// Assign each color role an actual color.
///
/// It implements `Index` and `IndexMut` to access and modify this mapping:
///
/// # Example
///
/// ```rust
/// # use cursive::theme::Palette;
/// use cursive::theme::PaletteColor::*;
/// use cursive::theme::Color::*;
/// use cursive::theme::BaseColor::*;
///
/// let mut palette = Palette::default();
///
/// assert_eq!(palette[Background], Dark(Blue));
/// palette[Shadow] = Light(Red);
/// ```
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Palette {
    basic: EnumMap<PaletteColor, Color>,
    custom: HashMap<String, PaletteNode>,
}

/// A node in the palette tree.
///
/// This describes a value attached to a custom keyword in the palette.
///
/// This can either be a color, or a nested namespace with its own mapping.
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum PaletteNode {
    /// A single color.
    Color(Color),
    /// A group of values bundled in the same namespace.
    ///
    /// Namespaces can be merged in the palette with `Palette::merge`.
    Namespace(HashMap<String, PaletteNode>),
}

// Basic usage: only use basic colors
impl Index<PaletteColor> for Palette {
    type Output = Color;

    fn index(&self, palette_color: PaletteColor) -> &Color {
        &self.basic[palette_color]
    }
}

// We can alter existing color if needed (but why?...)
impl IndexMut<PaletteColor> for Palette {
    fn index_mut(&mut self, palette_color: PaletteColor) -> &mut Color {
        &mut self.basic[palette_color]
    }
}

impl Palette {
    /// Returns a custom color from this palette.
    ///
    /// Returns `None` if the given key was not found.
    pub fn custom<'a>(&'a self, key: &str) -> Option<&'a Color> {
        self.custom.get(key).and_then(|node| {
            if let PaletteNode::Color(ref color) = *node {
                Some(color)
            } else {
                None
            }
        })
    }

    /// Returns a new palette where the given namespace has been merged.
    ///
    /// All values in the namespace will override previous values.
    pub fn merge(&self, namespace: &str) -> Palette {
        let mut result = self.clone();

        if let Some(&PaletteNode::Namespace(ref palette)) =
            self.custom.get(namespace)
        {
            // Merge `result` and `palette`
            for (key, value) in palette.iter() {
                match *value {
                    PaletteNode::Color(color) => result.set_color(key, color),
                    PaletteNode::Namespace(ref map) => {
                        result.add_namespace(key, map.clone())
                    }
                }
            }
        }

        result
    }

    /// Sets the color for the given key.
    ///
    /// This will update either the basic palette or the custom values.
    pub fn set_color(&mut self, key: &str, color: Color) {
        use crate::theme::PaletteColor::*;

        match key {
            "background" => self.basic[Background] = color,
            "shadow" => self.basic[Shadow] = color,
            "view" => self.basic[View] = color,
            "primary" => self.basic[Primary] = color,
            "secondary" => self.basic[Secondary] = color,
            "tertiary" => self.basic[Tertiary] = color,
            "title_primary" => self.basic[TitlePrimary] = color,
            "title_secondary" => self.basic[TitleSecondary] = color,
            "highlight" => self.basic[Highlight] = color,
            "highlight_inactive" => self.basic[HighlightInactive] = color,
            other => {
                self.custom
                    .insert(other.to_string(), PaletteNode::Color(color));
            }
        }
    }

    /// Adds a color namespace to this palette.
    pub fn add_namespace(
        &mut self,
        key: &str,
        namespace: HashMap<String, PaletteNode>,
    ) {
        self.custom
            .insert(key.to_string(), PaletteNode::Namespace(namespace));
    }
}

/// Returns the default palette for a cursive application.
///
/// * `Background` => `Dark(Blue)`
/// * `Shadow` => `Dark(Black)`
/// * `View` => `Dark(White)`
/// * `Primary` => `Dark(Black)`
/// * `Secondary` => `Dark(Blue)`
/// * `Tertiary` => `Dark(White)`
/// * `TitlePrimary` => `Dark(Red)`
/// * `TitleSecondary` => `Dark(Yellow)`
/// * `Highlight` => `Dark(Red)`
/// * `HighlightInactive` => `Dark(Blue)`
impl Default for Palette {
    fn default() -> Palette {
        use self::PaletteColor::*;
        use crate::theme::BaseColor::*;
        use crate::theme::Color::*;

        Palette {
            basic: enum_map! {
                Background => Dark(Blue),
                Shadow => Dark(Black),
                View => Dark(White),
                Primary => Dark(Black),
                Secondary => Dark(Blue),
                Tertiary => Dark(White),
                TitlePrimary => Dark(Red),
                TitleSecondary => Dark(Yellow),
                Highlight => Dark(Red),
                HighlightInactive => Dark(Blue),
            },
            custom: HashMap::new(),
        }
    }
}

// Iterate over a toml
fn iterate_toml<'a>(
    table: &'a toml::value::Table,
) -> impl Iterator<Item = (&'a str, PaletteNode)> + 'a {
    table.iter().flat_map(|(key, value)| {
        let node = match value {
            toml::Value::Table(table) => {
                // This should define a new namespace
                // Treat basic colors as simple string.
                // We'll convert them back in the merge method.
                let map = iterate_toml(table)
                    .map(|(key, value)| (key.to_string(), value))
                    .collect();
                // Should we only return something if it's non-empty?
                Some(PaletteNode::Namespace(map))
            }
            toml::Value::Array(colors) => {
                // This should be a list of colors - just pick the first valid one.
                colors
                    .iter()
                    .flat_map(toml::Value::as_str)
                    .flat_map(Color::parse)
                    .map(PaletteNode::Color)
                    .next()
            }
            toml::Value::String(color) => {
                // This describe a new color - easy!
                Color::parse(color).map(PaletteNode::Color)
            }
            other => {
                // Other - error?
                warn!(
                    "Found unexpected value in theme: {} = {:?}",
                    key, other
                );
                None
            }
        };

        node.map(|node| (key.as_str(), node))
    })
}

/// Fills `palette` with the colors from the given `table`.
pub(crate) fn load_toml(palette: &mut Palette, table: &toml::value::Table) {
    // TODO: use serde for that?
    // Problem: toml-rs doesn't do well with Enums...

    for (key, value) in iterate_toml(table) {
        match value {
            PaletteNode::Color(color) => palette.set_color(key, color),
            PaletteNode::Namespace(map) => palette.add_namespace(key, map),
        }
    }
}

/// Color entry in a palette.
///
/// Each `PaletteColor` is used for a specific role in a default application.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Enum)]
pub enum PaletteColor {
    /// Color used for the application background.
    Background,
    /// Color used for View shadows.
    Shadow,
    /// Color used for View backgrounds.
    View,
    /// Primary color used for the text.
    Primary,
    /// Secondary color used for the text.
    Secondary,
    /// Tertiary color used for the text.
    Tertiary,
    /// Primary color used for title text.
    TitlePrimary,
    /// Secondary color used for title text.
    TitleSecondary,
    /// Color used for highlighting text.
    Highlight,
    /// Color used for highlighting inactive text.
    HighlightInactive,
}

impl PaletteColor {
    /// Given a palette, resolve `self` to a concrete color.
    pub fn resolve(self, palette: &Palette) -> Color {
        palette[self]
    }
}
<commit_msg>Change `TitleSecondary` from Yellow to Light Blue (#376)<commit_after>use super::Color;
use enum_map::{enum_map, Enum, EnumMap};
use log::warn;
use toml;

use hashbrown::HashMap;
use std::ops::{Index, IndexMut};

/// Color configuration for the application.
///
/// Assign each color role an actual color.
///
/// It implements `Index` and `IndexMut` to access and modify this mapping:
///
/// # Example
///
/// ```rust
/// # use cursive::theme::Palette;
/// use cursive::theme::PaletteColor::*;
/// use cursive::theme::Color::*;
/// use cursive::theme::BaseColor::*;
///
/// let mut palette = Palette::default();
///
/// assert_eq!(palette[Background], Dark(Blue));
/// palette[Shadow] = Light(Red);
/// ```
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Palette {
    basic: EnumMap<PaletteColor, Color>,
    custom: HashMap<String, PaletteNode>,
}

/// A node in the palette tree.
///
/// This describes a value attached to a custom keyword in the palette.
///
/// This can either be a color, or a nested namespace with its own mapping.
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum PaletteNode {
    /// A single color.
    Color(Color),
    /// A group of values bundled in the same namespace.
    ///
    /// Namespaces can be merged in the palette with `Palette::merge`.
    Namespace(HashMap<String, PaletteNode>),
}

// Basic usage: only use basic colors
impl Index<PaletteColor> for Palette {
    type Output = Color;

    fn index(&self, palette_color: PaletteColor) -> &Color {
        &self.basic[palette_color]
    }
}

// We can alter existing color if needed (but why?...)
impl IndexMut<PaletteColor> for Palette {
    fn index_mut(&mut self, palette_color: PaletteColor) -> &mut Color {
        &mut self.basic[palette_color]
    }
}

impl Palette {
    /// Returns a custom color from this palette.
    ///
    /// Returns `None` if the given key was not found.
    pub fn custom<'a>(&'a self, key: &str) -> Option<&'a Color> {
        self.custom.get(key).and_then(|node| {
            if let PaletteNode::Color(ref color) = *node {
                Some(color)
            } else {
                None
            }
        })
    }

    /// Returns a new palette where the given namespace has been merged.
    ///
    /// All values in the namespace will override previous values.
    pub fn merge(&self, namespace: &str) -> Palette {
        let mut result = self.clone();

        if let Some(&PaletteNode::Namespace(ref palette)) =
            self.custom.get(namespace)
        {
            // Merge `result` and `palette`
            for (key, value) in palette.iter() {
                match *value {
                    PaletteNode::Color(color) => result.set_color(key, color),
                    PaletteNode::Namespace(ref map) => {
                        result.add_namespace(key, map.clone())
                    }
                }
            }
        }

        result
    }

    /// Sets the color for the given key.
    ///
    /// This will update either the basic palette or the custom values.
    pub fn set_color(&mut self, key: &str, color: Color) {
        use crate::theme::PaletteColor::*;

        match key {
            "background" => self.basic[Background] = color,
            "shadow" => self.basic[Shadow] = color,
            "view" => self.basic[View] = color,
            "primary" => self.basic[Primary] = color,
            "secondary" => self.basic[Secondary] = color,
            "tertiary" => self.basic[Tertiary] = color,
            "title_primary" => self.basic[TitlePrimary] = color,
            "title_secondary" => self.basic[TitleSecondary] = color,
            "highlight" => self.basic[Highlight] = color,
            "highlight_inactive" => self.basic[HighlightInactive] = color,
            other => {
                self.custom
                    .insert(other.to_string(), PaletteNode::Color(color));
            }
        }
    }

    /// Adds a color namespace to this palette.
    pub fn add_namespace(
        &mut self,
        key: &str,
        namespace: HashMap<String, PaletteNode>,
    ) {
        self.custom
            .insert(key.to_string(), PaletteNode::Namespace(namespace));
    }
}

/// Returns the default palette for a cursive application.
///
/// * `Background` => `Dark(Blue)`
/// * `Shadow` => `Dark(Black)`
/// * `View` => `Dark(White)`
/// * `Primary` => `Dark(Black)`
/// * `Secondary` => `Dark(Blue)`
/// * `Tertiary` => `Dark(White)`
/// * `TitlePrimary` => `Dark(Red)`
/// * `TitleSecondary` => `Dark(Yellow)`
/// * `Highlight` => `Dark(Red)`
/// * `HighlightInactive` => `Dark(Blue)`
impl Default for Palette {
    fn default() -> Palette {
        use self::PaletteColor::*;
        use crate::theme::BaseColor::*;
        use crate::theme::Color::*;

        Palette {
            basic: enum_map! {
                Background => Dark(Blue),
                Shadow => Dark(Black),
                View => Dark(White),
                Primary => Dark(Black),
                Secondary => Dark(Blue),
                Tertiary => Dark(White),
                TitlePrimary => Dark(Red),
                TitleSecondary => Light(Blue),
                Highlight => Dark(Red),
                HighlightInactive => Dark(Blue),
            },
            custom: HashMap::new(),
        }
    }
}

// Iterate over a toml
fn iterate_toml<'a>(
    table: &'a toml::value::Table,
) -> impl Iterator<Item = (&'a str, PaletteNode)> + 'a {
    table.iter().flat_map(|(key, value)| {
        let node = match value {
            toml::Value::Table(table) => {
                // This should define a new namespace
                // Treat basic colors as simple string.
                // We'll convert them back in the merge method.
                let map = iterate_toml(table)
                    .map(|(key, value)| (key.to_string(), value))
                    .collect();
                // Should we only return something if it's non-empty?
                Some(PaletteNode::Namespace(map))
            }
            toml::Value::Array(colors) => {
                // This should be a list of colors - just pick the first valid one.
                colors
                    .iter()
                    .flat_map(toml::Value::as_str)
                    .flat_map(Color::parse)
                    .map(PaletteNode::Color)
                    .next()
            }
            toml::Value::String(color) => {
                // This describe a new color - easy!
                Color::parse(color).map(PaletteNode::Color)
            }
            other => {
                // Other - error?
                warn!(
                    "Found unexpected value in theme: {} = {:?}",
                    key, other
                );
                None
            }
        };

        node.map(|node| (key.as_str(), node))
    })
}

/// Fills `palette` with the colors from the given `table`.
pub(crate) fn load_toml(palette: &mut Palette, table: &toml::value::Table) {
    // TODO: use serde for that?
    // Problem: toml-rs doesn't do well with Enums...

    for (key, value) in iterate_toml(table) {
        match value {
            PaletteNode::Color(color) => palette.set_color(key, color),
            PaletteNode::Namespace(map) => palette.add_namespace(key, map),
        }
    }
}

/// Color entry in a palette.
///
/// Each `PaletteColor` is used for a specific role in a default application.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Enum)]
pub enum PaletteColor {
    /// Color used for the application background.
    Background,
    /// Color used for View shadows.
    Shadow,
    /// Color used for View backgrounds.
    View,
    /// Primary color used for the text.
    Primary,
    /// Secondary color used for the text.
    Secondary,
    /// Tertiary color used for the text.
    Tertiary,
    /// Primary color used for title text.
    TitlePrimary,
    /// Secondary color used for title text.
    TitleSecondary,
    /// Color used for highlighting text.
    Highlight,
    /// Color used for highlighting inactive text.
    HighlightInactive,
}

impl PaletteColor {
    /// Given a palette, resolve `self` to a concrete color.
    pub fn resolve(self, palette: &Palette) -> Color {
        palette[self]
    }
}
<|endoftext|>


<commit_before>// unix/ctl_iter.rs

use super::ctl::Ctl;
use super::funcs::next_oid;
use ctl_error::SysctlError;

/// An iterator over Sysctl entries.
pub struct CtlIter {
    // if we are iterating over a Node, only include OIDs
    // starting with this base. Set to None if iterating over all
    // OIDs.
    base: Ctl,
    current: Ctl,
}

impl CtlIter {
    /// Return an iterator over the complete sysctl tree.
    pub fn root() -> Self {
        CtlIter {
            base: Ctl { oid: vec![] },
            current: Ctl { oid: vec![1] },
        }
    }

    /// Return an iterator over all sysctl entries below the given node.
    pub fn below(node: Ctl) -> Self {
        CtlIter {
            base: node.clone(),
            current: node,
        }
    }
}

impl Iterator for CtlIter {
    type Item = Result<Ctl, SysctlError>;

    fn next(&mut self) -> Option<Self::Item> {
        let oid = match next_oid(&self.current.oid) {
            Ok(Some(o)) => o,
            Err(e) => return Some(Err(e)),
            Ok(None) => return None,
        };

        // We continue iterating as long as the oid starts with the base
        let cont = oid.starts_with(&self.base.oid);

        self.current = Ctl { oid };

        match cont {
            true => Some(Ok(self.current.clone())),
            false => None,
        }
    }
}

/// Ctl implements the IntoIterator trait to allow for easy iteration
/// over nodes.
///
/// # Example
///
/// ```
/// use sysctl::Sysctl;
///
/// let kern = sysctl::Ctl::new("kern");
/// for ctl in kern {
///     println!("{}", ctl.name().unwrap());
/// }
/// ```
impl IntoIterator for Ctl {
    type Item = Result<Ctl, SysctlError>;
    type IntoIter = CtlIter;

    fn into_iter(self) -> Self::IntoIter {
        CtlIter::below(self)
    }
}

#[cfg(test)]
mod tests {
    use crate::Sysctl;

    #[test]
    fn ctl_iter_iterate_all() {
        let root = super::CtlIter::root();
        let all_ctls: Vec<super::Ctl> = root.into_iter().filter_map(Result::ok).collect();
        assert_ne!(all_ctls.len(), 0);
        for ctl in &all_ctls {
            println!("{:?}", ctl.name());
        }
    }

    #[test]
    fn ctl_iter_below_compare_outputs() {
        let output = std::process::Command::new("sysctl")
            .arg("security")
            .output()
            .expect("failed to execute process");
        let expected = String::from_utf8_lossy(&output.stdout);

        let security = super::Ctl::new("security").expect("could not get security node");

        let ctls = super::CtlIter::below(security);
        let mut actual: Vec<String> = vec!["".to_string()];

        for ctl in ctls {
            let ctl = match ctl {
                Err(_) => {
                    continue;
                }
                Ok(s) => s,
            };

            let name = match ctl.name() {
                Ok(s) => s,
                Err(_) => {
                    continue;
                }
            };

            match ctl.value_type().expect("could not get value type") {
                crate::CtlType::None => {
                    continue;
                }
                crate::CtlType::Struct => {
                    continue;
                }
                crate::CtlType::Node => {
                    continue;
                }
                #[cfg(not(target_os = "macos"))]
                crate::CtlType::Temperature => {
                    continue;
                }
                _ => {}
            };

            actual.push(format!(
                "{}: {}",
                name,
                ctl.value_string().expect("could not get value as string")
            ));
        }
        assert_eq!(actual.join("\n").trim(), expected.trim());
    }
}
<commit_msg>Remove test ctl_iter_below_compare_outputs since its not reliable.<commit_after>// unix/ctl_iter.rs

use super::ctl::Ctl;
use super::funcs::next_oid;
use ctl_error::SysctlError;

/// An iterator over Sysctl entries.
pub struct CtlIter {
    // if we are iterating over a Node, only include OIDs
    // starting with this base. Set to None if iterating over all
    // OIDs.
    base: Ctl,
    current: Ctl,
}

impl CtlIter {
    /// Return an iterator over the complete sysctl tree.
    pub fn root() -> Self {
        CtlIter {
            base: Ctl { oid: vec![] },
            current: Ctl { oid: vec![1] },
        }
    }

    /// Return an iterator over all sysctl entries below the given node.
    pub fn below(node: Ctl) -> Self {
        CtlIter {
            base: node.clone(),
            current: node,
        }
    }
}

impl Iterator for CtlIter {
    type Item = Result<Ctl, SysctlError>;

    fn next(&mut self) -> Option<Self::Item> {
        let oid = match next_oid(&self.current.oid) {
            Ok(Some(o)) => o,
            Err(e) => return Some(Err(e)),
            Ok(None) => return None,
        };

        // We continue iterating as long as the oid starts with the base
        let cont = oid.starts_with(&self.base.oid);

        self.current = Ctl { oid };

        match cont {
            true => Some(Ok(self.current.clone())),
            false => None,
        }
    }
}

/// Ctl implements the IntoIterator trait to allow for easy iteration
/// over nodes.
///
/// # Example
///
/// ```
/// use sysctl::Sysctl;
///
/// let kern = sysctl::Ctl::new("kern");
/// for ctl in kern {
///     println!("{}", ctl.name().unwrap());
/// }
/// ```
impl IntoIterator for Ctl {
    type Item = Result<Ctl, SysctlError>;
    type IntoIter = CtlIter;

    fn into_iter(self) -> Self::IntoIter {
        CtlIter::below(self)
    }
}

#[cfg(test)]
mod tests {
    use crate::Sysctl;

    #[test]
    fn ctl_iter_iterate_all() {
        let root = super::CtlIter::root();
        let all_ctls: Vec<super::Ctl> = root.into_iter().filter_map(Result::ok).collect();
        assert_ne!(all_ctls.len(), 0);
        for ctl in &all_ctls {
            println!("{:?}", ctl.name());
        }
    }
}
<|endoftext|>


<commit_before>//! # Flexibly-sized reusable boxes
//!
//! `FlexBox` provides a reusable `Box`-like storage mechanism.  Like `Box` it
//! allows dynamic dispatch by wrapping of trait objects; however, it also
//! allows the allocated memory to be used multiple times.
//!
//! ```rust
//! use cripes::util::flex_box::{FlexBox,Ref};
//!
//! fn some_iter<'a>(dest: &'a mut FlexBox) -> Ref<'a,Iterator<Item=u8>> {
//!     dest.store(std::iter::once(42))
//! }
//!
//! fn main() {
//!     let mut flex_box = FlexBox::new();
//!     let iter = some_iter(&mut flex_box);
//!     println!("{:?}", iter.collect::<Vec<u8>>());
//! }
//! ```
use std;
use std::fmt;
use std::ptr;
use std::iter::Iterator;
use std::mem::{align_of,size_of};
use std::intrinsics::move_val_init;
use std::ops::Drop;
extern crate alloc;
use self::alloc::heap::{allocate,deallocate,reallocate};

/// A flexibly-sized, reusable `Box`-like container.
pub struct FlexBox {
    buf: *mut u8,
    capacity: usize,
    align: usize
}

impl FlexBox {
    /// Create a new FlexBox with zero capacity.
    pub fn new() -> Self {
        FlexBox{buf: ptr::null_mut(), capacity: 0, align: 0}
    }

    /// Create a new FlexBox with capacity and alignment sufficient to hold
    /// a value of the given type.
    pub fn with_capacity_for<T>() -> Self {
        let mut out = Self::new();
        if size_of::<T>() > 0 { out.ensure_capacity::<T>(); }

        out
    }

    /// Ensure that the buffer has sufficient capacity and alignment to hold
    /// a value of the specified type.
    fn ensure_capacity<T>(&mut self) {
        let size = size_of::<T>();
        let align = align_of::<T>();
        if size > 0 {
            unsafe {
                let new = if self.buf.is_null() {
                    allocate(size, align)
                } else if self.capacity < size || self.align < align {
                    reallocate(self.buf, self.capacity, size, align)
                } else {
                    ptr::null_mut()
                };

                if !new.is_null() {
                    self.buf = new;
                    self.capacity = size;
                    self.align = align;
                }
            }
        }
    }

    /// Move a value into the FlexBox, and return a reference to it.
    /// The stored value will be dropped at the same time as the returned
    /// reference is dropped.
    pub fn store<'a,T>(&'a mut self, obj: T) -> Ref<'a,T> {
        self.ensure_capacity::<T>();

        assert!(self.capacity >= size_of::<T>());
        let dest = unsafe { &mut *(self.buf as *mut T) };
        unsafe { move_val_init(dest, obj) };
        Ref(dest)
    }
}

impl Drop for FlexBox {
    fn drop(&mut self) {
        if ! self.buf.is_null() {
            unsafe { deallocate(self.buf, self.capacity, self.align); }
            self.buf = ptr::null_mut();
            self.capacity = 0;
            self.align = 0; }
    }
}

/// Reference to a live value stored in a `FlexBox`.  `Ref` directly manages
/// the lifetime of the stored value: the value is dropped at the same time as
/// the `Ref` that refers to it.
pub struct Ref<'a,T: 'a + ?Sized>(&'a mut T);

impl<'a,U: 'a + ?Sized, T: 'a + ?Sized + std::marker::Unsize<U>>
    std::ops::CoerceUnsized<Ref<'a,U>>
    for Ref<'a,T>
    {}

impl<'a,T: 'a + ?Sized> Drop for Ref<'a,T> {
    fn drop(&mut self) {
        unsafe { std::intrinsics::drop_in_place(self.0); }
    }
}

impl<'a,T: 'a + ?Sized> std::ops::Deref for Ref<'a,T> {
    type Target = T;
    fn deref<'b>(&'b self) -> &'b T {
        &*self.0
    }
}

impl<'a,T: 'a + ?Sized> std::ops::DerefMut for Ref<'a,T> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        &mut *self.0
    }
}

/* **************************************************************** */
// Utility implementations follow.

// I'll admit that this macro is a bit excessive, but it's adapted from
// something similar I had lying around anyway.
macro_rules! passthrough {
    /* (&self) */
    ($implemented: path, $method:ident(&self))
        => (fn $method(&self) { T::$method(&*self) });

    /* (&self, ...) */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+))
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&self) -> ... */
    ($implemented: path, $method:ident(&self) -> $ret:ty)
        => (fn $method(&self) -> $ret { T::$method(&*self) });

    /* (&self, ...) -> ... */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&mut self) */
    ($implemented: path, $method:ident(&mut self))
        => (fn $method(&mut self) { T::$method(&mut *self) });

    /* (&mut self, ...) */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+))
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });

    /* (&mut self) -> ... */
    ($implemented: path, $method:ident(&mut self) -> $ret:ty)
        => (fn $method(&mut self) -> $ret { T::$method(&mut *self) });

    /* (&mut self, ...) -> ... */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });
}

impl<'a,T: 'a + ?Sized + fmt::Debug> fmt::Debug for Ref<'a,T> {
    passthrough!(fmt::Debug, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,T: 'a + ?Sized + fmt::Display> fmt::Display for Ref<'a,T> {
    passthrough!(fmt::Display, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,U,T: ?Sized> Iterator for Ref<'a,T> where T: 'a + Iterator<Item=U> {
    type Item = U;

    passthrough!(Iterator, next(&mut self) -> Option<U>);
    passthrough!(Iterator, size_hint(&self) -> (usize, Option<usize>));
}
<commit_msg>util/flex_box.rs: clarify the final `else` branch in `ensure_capacity`<commit_after>//! # Flexibly-sized reusable boxes
//!
//! `FlexBox` provides a reusable `Box`-like storage mechanism.  Like `Box` it
//! allows dynamic dispatch by wrapping of trait objects; however, it also
//! allows the allocated memory to be used multiple times.
//!
//! ```rust
//! use cripes::util::flex_box::{FlexBox,Ref};
//!
//! fn some_iter<'a>(dest: &'a mut FlexBox) -> Ref<'a,Iterator<Item=u8>> {
//!     dest.store(std::iter::once(42))
//! }
//!
//! fn main() {
//!     let mut flex_box = FlexBox::new();
//!     let iter = some_iter(&mut flex_box);
//!     println!("{:?}", iter.collect::<Vec<u8>>());
//! }
//! ```
use std;
use std::fmt;
use std::ptr;
use std::iter::Iterator;
use std::mem::{align_of,size_of};
use std::intrinsics::move_val_init;
use std::ops::Drop;
extern crate alloc;
use self::alloc::heap::{allocate,deallocate,reallocate};

/// A flexibly-sized, reusable `Box`-like container.
pub struct FlexBox {
    buf: *mut u8,
    capacity: usize,
    align: usize
}

impl FlexBox {
    /// Create a new FlexBox with zero capacity.
    pub fn new() -> Self {
        FlexBox{buf: ptr::null_mut(), capacity: 0, align: 0}
    }

    /// Create a new FlexBox with capacity and alignment sufficient to hold
    /// a value of the given type.
    pub fn with_capacity_for<T>() -> Self {
        let mut out = Self::new();
        if size_of::<T>() > 0 { out.ensure_capacity::<T>(); }

        out
    }

    /// Ensure that the buffer has sufficient capacity and alignment to hold
    /// a value of the specified type.
    fn ensure_capacity<T>(&mut self) {
        let size = size_of::<T>();
        let align = align_of::<T>();
        if size > 0 {
            unsafe {
                let new = if self.buf.is_null() {
                    allocate(size, align)
                } else if self.capacity < size || self.align < align {
                    reallocate(self.buf, self.capacity, size, align)
                } else {
                    // We use a null value for the new-buffer pointer to
                    // indicate that no (re)allocation is necessary.
                    ptr::null_mut()
                };

                if !new.is_null() {
                    self.buf = new;
                    self.capacity = size;
                    self.align = align;
                }
            }
        }
    }

    /// Move a value into the FlexBox, and return a reference to it.
    /// The stored value will be dropped at the same time as the returned
    /// reference is dropped.
    pub fn store<'a,T>(&'a mut self, obj: T) -> Ref<'a,T> {
        self.ensure_capacity::<T>();

        assert!(self.capacity >= size_of::<T>());
        let dest = unsafe { &mut *(self.buf as *mut T) };
        unsafe { move_val_init(dest, obj) };
        Ref(dest)
    }
}

impl Drop for FlexBox {
    fn drop(&mut self) {
        if ! self.buf.is_null() {
            unsafe { deallocate(self.buf, self.capacity, self.align); }
            self.buf = ptr::null_mut();
            self.capacity = 0;
            self.align = 0; }
    }
}

/// Reference to a live value stored in a `FlexBox`.  `Ref` directly manages
/// the lifetime of the stored value: the value is dropped at the same time as
/// the `Ref` that refers to it.
pub struct Ref<'a,T: 'a + ?Sized>(&'a mut T);

impl<'a,U: 'a + ?Sized, T: 'a + ?Sized + std::marker::Unsize<U>>
    std::ops::CoerceUnsized<Ref<'a,U>>
    for Ref<'a,T>
    {}

impl<'a,T: 'a + ?Sized> Drop for Ref<'a,T> {
    fn drop(&mut self) {
        unsafe { std::intrinsics::drop_in_place(self.0); }
    }
}

impl<'a,T: 'a + ?Sized> std::ops::Deref for Ref<'a,T> {
    type Target = T;
    fn deref<'b>(&'b self) -> &'b T {
        &*self.0
    }
}

impl<'a,T: 'a + ?Sized> std::ops::DerefMut for Ref<'a,T> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        &mut *self.0
    }
}

/* **************************************************************** */
// Utility implementations follow.

// I'll admit that this macro is a bit excessive, but it's adapted from
// something similar I had lying around anyway.
macro_rules! passthrough {
    /* (&self) */
    ($implemented: path, $method:ident(&self))
        => (fn $method(&self) { T::$method(&*self) });

    /* (&self, ...) */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+))
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&self) -> ... */
    ($implemented: path, $method:ident(&self) -> $ret:ty)
        => (fn $method(&self) -> $ret { T::$method(&*self) });

    /* (&self, ...) -> ... */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&mut self) */
    ($implemented: path, $method:ident(&mut self))
        => (fn $method(&mut self) { T::$method(&mut *self) });

    /* (&mut self, ...) */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+))
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });

    /* (&mut self) -> ... */
    ($implemented: path, $method:ident(&mut self) -> $ret:ty)
        => (fn $method(&mut self) -> $ret { T::$method(&mut *self) });

    /* (&mut self, ...) -> ... */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });
}

impl<'a,T: 'a + ?Sized + fmt::Debug> fmt::Debug for Ref<'a,T> {
    passthrough!(fmt::Debug, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,T: 'a + ?Sized + fmt::Display> fmt::Display for Ref<'a,T> {
    passthrough!(fmt::Display, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,U,T: ?Sized> Iterator for Ref<'a,T> where T: 'a + Iterator<Item=U> {
    type Item = U;

    passthrough!(Iterator, next(&mut self) -> Option<U>);
    passthrough!(Iterator, size_hint(&self) -> (usize, Option<usize>));
}
<|endoftext|>


<commit_before>use llvm_sys::prelude::LLVMValueRef;
use llvm_sys::core::{LLVMConstExtractValue, LLVMConstInsertValue};

use std::fmt::Debug;

use crate::values::{ArrayValue, AggregateValueEnum, BasicValueUse, CallSiteValue, GlobalValue, StructValue, BasicValueEnum, AnyValueEnum, IntValue, FloatValue, PointerValue, PhiValue, VectorValue, FunctionValue, InstructionValue, Value};
use crate::types::{IntMathType, FloatMathType, PointerMathType, IntType, FloatType, PointerType, VectorType};

// This is an ugly privacy hack so that Type can stay private to this module
// and so that super traits using this trait will be not be implementable
// outside this library
pub trait AsValueRef {
    fn as_value_ref(&self) -> LLVMValueRef;
}

macro_rules! trait_value_set {
    ($trait_name:ident: $($args:ident),*) => (
        $(
            impl $trait_name for $args {}
        )*

        // REVIEW: Possible encompassing methods to implement:
        // as_instruction, is_sized, ge/set metadata methods
    );
}

macro_rules! math_trait_value_set {
    ($trait_name:ident: $(($value_type:ident => $base_type:ident)),*) => (
        $(
            impl $trait_name for $value_type {
                type BaseType = $base_type;
                fn new(value: LLVMValueRef) -> Self {
                    $value_type::new(value)
                }
            }
        )*
    )
}

/// Represents an aggregate value, built on top of other values.
pub trait AggregateValue: BasicValue {
    /// Returns an enum containing a typed version of the `AggregateValue`.
    fn as_aggregate_value_enum(&self) -> AggregateValueEnum {
        AggregateValueEnum::new(self.as_value_ref())
    }

    // REVIEW: How does LLVM treat out of bound index? Maybe we should return an Option?
    // or is that only in bounds GEP
    // REVIEW: Should this be AggregatePointerValue?
    fn const_extract_value(&self, indexes: &mut [u32]) -> BasicValueEnum {
        let value = unsafe {
            LLVMConstExtractValue(self.as_value_ref(), indexes.as_mut_ptr(), indexes.len() as u32)
        };

        BasicValueEnum::new(value)
    }

    // SubTypes: value should really be T in self: VectorValue<T> I think
    fn const_insert_value<BV: BasicValue>(&self, value: BV, indexes: &mut [u32]) -> BasicValueEnum {
        let value = unsafe {
            LLVMConstInsertValue(self.as_value_ref(), value.as_value_ref(), indexes.as_mut_ptr(), indexes.len() as u32)
        };

        BasicValueEnum::new(value)
    }
}

/// Represents a basic value, which can be used both by itself, or in an `AggregateValue`.
pub trait BasicValue: AnyValue {
    /// Returns an enum containing a typed version of the `BasicValue`.
    fn as_basic_value_enum(&self) -> BasicValueEnum {
        BasicValueEnum::new(self.as_value_ref())
    }

    /// Most `BasicValue`s are the byproduct of an instruction
    /// and so are convertable into an `InstructionValue`
    fn as_instruction_value(&self) -> Option<InstructionValue> {
        let value = Value::new(self.as_value_ref());

        if !value.is_instruction() {
            return None;
        }

        Some(InstructionValue::new(self.as_value_ref()))
    }

    fn get_first_use(&self) -> Option<BasicValueUse> {
        Value::new(self.as_value_ref()).get_first_use()
    }

    // REVIEW: Possible encompassing methods to implement:
    // is_sized, get/set metadata
}

/// Represents a value which is permitted in integer math operations
pub trait IntMathValue: BasicValue {
    type BaseType: IntMathType;
    fn new(value: LLVMValueRef) -> Self;
}

/// Represents a value which is permitted in floating point math operations
pub trait FloatMathValue: BasicValue {
    type BaseType: FloatMathType;
    fn new(value: LLVMValueRef) -> Self;
}

pub trait PointerMathValue: BasicValue {
    type BaseType: PointerMathType;
    fn new(value: LLVMValueRef) -> Self;
}

// REVIEW: print_to_string might be a good candidate to live here?
/// Defines any struct wrapping an LLVM value.
pub trait AnyValue: AsValueRef + Debug {
    /// Returns an enum containing a typed version of `AnyValue`.
    fn as_any_value_enum(&self) -> AnyValueEnum {
        AnyValueEnum::new(self.as_value_ref())
    }
}

trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, GlobalValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, InstructionValue, CallSiteValue}
trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, GlobalValue, StructValue, PointerValue, VectorValue}
math_trait_value_set! {IntMathValue: (IntValue => IntType), (VectorValue => VectorType)}
math_trait_value_set! {FloatMathValue: (FloatValue => FloatType), (VectorValue => VectorType)}
math_trait_value_set! {PointerMathValue: (PointerValue => PointerType), (VectorValue => VectorType)}
<commit_msg>Add TryFrom traits from BasicValueEnum and BasicTypeEnum.<commit_after>use llvm_sys::prelude::LLVMValueRef;
use llvm_sys::core::{LLVMConstExtractValue, LLVMConstInsertValue};

use std::convert::TryFrom;
use std::fmt::Debug;

use crate::values::{ArrayValue, AggregateValueEnum, BasicValueUse, CallSiteValue, GlobalValue, StructValue, BasicValueEnum, AnyValueEnum, IntValue, FloatValue, PointerValue, PhiValue, VectorValue, FunctionValue, InstructionValue, Value};
use crate::types::{ArrayType, BasicTypeEnum, IntMathType, FloatMathType, PointerMathType, IntType, FloatType, PointerType, StructType, VectorType};

// This is an ugly privacy hack so that Type can stay private to this module
// and so that super traits using this trait will be not be implementable
// outside this library
pub trait AsValueRef {
    fn as_value_ref(&self) -> LLVMValueRef;
}

macro_rules! trait_value_set {
    ($trait_name:ident: $($args:ident),*) => (
        $(
            impl $trait_name for $args {}
        )*

        // REVIEW: Possible encompassing methods to implement:
        // as_instruction, is_sized, ge/set metadata methods
    );
}

macro_rules! math_trait_value_set {
    ($trait_name:ident: $(($value_type:ident => $base_type:ident)),*) => (
        $(
            impl $trait_name for $value_type {
                type BaseType = $base_type;
                fn new(value: LLVMValueRef) -> Self {
                    $value_type::new(value)
                }
            }
        )*
    )
}

/// Represents an aggregate value, built on top of other values.
pub trait AggregateValue: BasicValue {
    /// Returns an enum containing a typed version of the `AggregateValue`.
    fn as_aggregate_value_enum(&self) -> AggregateValueEnum {
        AggregateValueEnum::new(self.as_value_ref())
    }

    // REVIEW: How does LLVM treat out of bound index? Maybe we should return an Option?
    // or is that only in bounds GEP
    // REVIEW: Should this be AggregatePointerValue?
    fn const_extract_value(&self, indexes: &mut [u32]) -> BasicValueEnum {
        let value = unsafe {
            LLVMConstExtractValue(self.as_value_ref(), indexes.as_mut_ptr(), indexes.len() as u32)
        };

        BasicValueEnum::new(value)
    }

    // SubTypes: value should really be T in self: VectorValue<T> I think
    fn const_insert_value<BV: BasicValue>(&self, value: BV, indexes: &mut [u32]) -> BasicValueEnum {
        let value = unsafe {
            LLVMConstInsertValue(self.as_value_ref(), value.as_value_ref(), indexes.as_mut_ptr(), indexes.len() as u32)
        };

        BasicValueEnum::new(value)
    }
}

/// Represents a basic value, which can be used both by itself, or in an `AggregateValue`.
pub trait BasicValue: AnyValue {
    /// Returns an enum containing a typed version of the `BasicValue`.
    fn as_basic_value_enum(&self) -> BasicValueEnum {
        BasicValueEnum::new(self.as_value_ref())
    }

    /// Most `BasicValue`s are the byproduct of an instruction
    /// and so are convertable into an `InstructionValue`
    fn as_instruction_value(&self) -> Option<InstructionValue> {
        let value = Value::new(self.as_value_ref());

        if !value.is_instruction() {
            return None;
        }

        Some(InstructionValue::new(self.as_value_ref()))
    }

    fn get_first_use(&self) -> Option<BasicValueUse> {
        Value::new(self.as_value_ref()).get_first_use()
    }

    // REVIEW: Possible encompassing methods to implement:
    // is_sized, get/set metadata
}

/// Represents a value which is permitted in integer math operations
pub trait IntMathValue: BasicValue {
    type BaseType: IntMathType;
    fn new(value: LLVMValueRef) -> Self;
}

/// Represents a value which is permitted in floating point math operations
pub trait FloatMathValue: BasicValue {
    type BaseType: FloatMathType;
    fn new(value: LLVMValueRef) -> Self;
}

pub trait PointerMathValue: BasicValue {
    type BaseType: PointerMathType;
    fn new(value: LLVMValueRef) -> Self;
}

// REVIEW: print_to_string might be a good candidate to live here?
/// Defines any struct wrapping an LLVM value.
pub trait AnyValue: AsValueRef + Debug {
    /// Returns an enum containing a typed version of `AnyValue`.
    fn as_any_value_enum(&self) -> AnyValueEnum {
        AnyValueEnum::new(self.as_value_ref())
    }
}

trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, GlobalValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, InstructionValue, CallSiteValue}
trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, GlobalValue, StructValue, PointerValue, VectorValue}
math_trait_value_set! {IntMathValue: (IntValue => IntType), (VectorValue => VectorType)}
math_trait_value_set! {FloatMathValue: (FloatValue => FloatType), (VectorValue => VectorType)}
math_trait_value_set! {PointerMathValue: (PointerValue => PointerType), (VectorValue => VectorType)}

macro_rules! impl_try_from_basic_value_enum {
    ($value_name:ident) => (
        impl TryFrom<BasicValueEnum> for $value_name {
            type Error = &'static str;

            fn try_from(value: BasicValueEnum) -> Result<Self, Self::Error> {
                match value {
                    BasicValueEnum::$value_name(value) => Ok(value),
                    _ => Err("bad try from"),
                }
            }
        }
    )
}

impl_try_from_basic_value_enum!(ArrayValue);
impl_try_from_basic_value_enum!(IntValue);
impl_try_from_basic_value_enum!(FloatValue);
impl_try_from_basic_value_enum!(PointerValue);
impl_try_from_basic_value_enum!(StructValue);
impl_try_from_basic_value_enum!(VectorValue);

macro_rules! impl_try_from_basic_type_enum {
    ($type_name:ident) => (
        impl TryFrom<BasicTypeEnum> for $type_name {
            type Error = &'static str;

            fn try_from(ty: BasicTypeEnum) -> Result<Self, Self::Error> {
                match ty {
                    BasicTypeEnum::$type_name(ty) => Ok(ty),
                    _ => Err("bad try from"),
                }
            }
        }
    )
}

impl_try_from_basic_type_enum!(ArrayType);
impl_try_from_basic_type_enum!(FloatType);
impl_try_from_basic_type_enum!(IntType);
impl_try_from_basic_type_enum!(PointerType);
impl_try_from_basic_type_enum!(StructType);
impl_try_from_basic_type_enum!(VectorType);
<|endoftext|>


<commit_before>use std::{
    fmt,
    sync::Arc,
    ptr
};

use {
    TextRange, TextUnit,
    SyntaxKind::{self, *},
    yellow::{RedNode, GreenNode},
};

#[derive(Clone, Copy)]
pub struct SyntaxNode<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone = Arc<SyntaxRoot>> {
    pub(crate) root: ROOT,
    // guaranteed to be alive bc SyntaxRoot holds a strong ref
    red: ptr::NonNull<RedNode>,
}

pub type SyntaxNodeRef<'a> = SyntaxNode<&'a SyntaxRoot>;

#[derive(Debug)]
pub struct SyntaxRoot {
    red: RedNode,
    pub(crate) errors: Vec<SyntaxError>,
}

impl SyntaxRoot {
    pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot {
        SyntaxRoot {
            red: RedNode::new_root(green),
            errors,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub(crate) struct SyntaxError {
    pub(crate) message: String,
    pub(crate) offset: TextUnit,
}

impl SyntaxNode<Arc<SyntaxRoot>> {
    pub(crate) fn new_owned(root: SyntaxRoot) -> Self {
        let root = Arc::new(root);
        let red_weak = ptr::NonNull::from(&root.red);
        SyntaxNode { root, red: red_weak }
    }
}

impl<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone> SyntaxNode<ROOT> {
    pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> {
        SyntaxNode {
            root: &*self.root,
            red: ptr::NonNull::clone(&self.red),
        }
    }

    pub fn kind(&self) -> SyntaxKind {
        self.red().green().kind()
    }

    pub fn range(&self) -> TextRange {
        let red = self.red();
        TextRange::offset_len(
            red.start_offset(),
            red.green().text_len(),
        )
    }

    pub fn text(&self) -> String {
        self.red().green().text()
    }

    pub fn children(&self) -> Vec<SyntaxNode<ROOT>> {
        let red = self.red();
        let n_children = red.n_children();
        let mut res = Vec::with_capacity(n_children);
        for i in 0..n_children {
            res.push(SyntaxNode {
                root: self.root.clone(),
                red: red.nth_child(i),
            });
        }
        res
    }

    fn red(&self) -> &RedNode {
        unsafe { self.red.as_ref() }
    }
}

impl<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone> fmt::Debug for SyntaxNode<ROOT> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
        if has_short_text(self.kind()) {
            write!(fmt, " \"{}\"", self.text())?;
        }
        Ok(())
    }
}

fn has_short_text(kind: SyntaxKind) -> bool {
    match kind {
        IDENT | LIFETIME => true,
        _ => false,
    }
}
<commit_msg>Trait for tree root<commit_after>use std::{
    fmt,
    sync::Arc,
    ptr,
    ops::Deref,
};

use {
    TextRange, TextUnit,
    SyntaxKind::{self, *},
    yellow::{RedNode, GreenNode},
};

pub trait TreeRoot: Deref<Target=SyntaxRoot> + Clone {}
impl TreeRoot for Arc<SyntaxRoot> {}
impl<'a> TreeRoot for &'a SyntaxRoot {}

#[derive(Clone, Copy)]
pub struct SyntaxNode<ROOT: TreeRoot = Arc<SyntaxRoot>> {
    pub(crate) root: ROOT,
    // guaranteed to be alive bc SyntaxRoot holds a strong ref
    red: ptr::NonNull<RedNode>,
}

pub type SyntaxNodeRef<'a> = SyntaxNode<&'a SyntaxRoot>;

#[derive(Debug)]
pub struct SyntaxRoot {
    red: RedNode,
    pub(crate) errors: Vec<SyntaxError>,
}

impl SyntaxRoot {
    pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot {
        SyntaxRoot {
            red: RedNode::new_root(green),
            errors,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub(crate) struct SyntaxError {
    pub(crate) message: String,
    pub(crate) offset: TextUnit,
}

impl SyntaxNode<Arc<SyntaxRoot>> {
    pub(crate) fn new_owned(root: SyntaxRoot) -> Self {
        let root = Arc::new(root);
        let red_weak = ptr::NonNull::from(&root.red);
        SyntaxNode { root, red: red_weak }
    }
}

impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
    pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> {
        SyntaxNode {
            root: &*self.root,
            red: ptr::NonNull::clone(&self.red),
        }
    }

    pub fn kind(&self) -> SyntaxKind {
        self.red().green().kind()
    }

    pub fn range(&self) -> TextRange {
        let red = self.red();
        TextRange::offset_len(
            red.start_offset(),
            red.green().text_len(),
        )
    }

    pub fn text(&self) -> String {
        self.red().green().text()
    }

    pub fn children(&self) -> Vec<SyntaxNode<ROOT>> {
        let red = self.red();
        let n_children = red.n_children();
        let mut res = Vec::with_capacity(n_children);
        for i in 0..n_children {
            res.push(SyntaxNode {
                root: self.root.clone(),
                red: red.nth_child(i),
            });
        }
        res
    }

    fn red(&self) -> &RedNode {
        unsafe { self.red.as_ref() }
    }
}

impl<ROOT: TreeRoot> fmt::Debug for SyntaxNode<ROOT> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
        if has_short_text(self.kind()) {
            write!(fmt, " \"{}\"", self.text())?;
        }
        Ok(())
    }
}

fn has_short_text(kind: SyntaxKind) -> bool {
    match kind {
        IDENT | LIFETIME => true,
        _ => false,
    }
}
<|endoftext|>


<commit_before>/// Graph data structures and algorithms

use std::collections::{HashMap, HashSet};

pub type NodeId = usize;

pub trait Graph<'a, V: 'a> {
    fn degree(&self, &V) -> usize;

    fn in_degree(&self, &V) -> usize;

    fn out_degree(&self, &V) -> usize;

    fn is_directed(&self) -> bool;

    fn contains_node(&self, &V) -> bool;

    fn nodes(&self) -> NodeIterator<'a, V>;

    fn adjacent_nodes(&self, &V) -> NodeIterator<'a, V>;

    fn predecessors(&self) -> NodeIterator<'a, V>;

    fn successors(&self) -> NodeIterator<'a, V>;

    fn edges(&self);

    fn is_connected(&self, v1: &V, v2: &V) -> bool;
}

pub trait MutableGraph<'a, V: 'a>: Graph<'a, V> {
    fn add_edge(&mut self, &V, &V);
}

pub trait ValueGraph<'a, V: 'a, E: 'a> : Graph<'a, V> {
    fn edge(&self, v1: &V, v2: &V) -> &E;
}

pub trait MutableValueGraph<'a, V: 'a, E: 'a>: ValueGraph<'a, V, E> {
    fn add_edge(&mut self, &V, &V, e: E);
}

pub struct NodeIterator<'a, V: 'a> {
    v: &'a V
}

impl<'a, V: 'a> Iterator for NodeIterator<'a, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<&'a V> {
        unimplemented!()
    }
}

pub struct GraphData<V> {
    directed: bool,
    loop_allowed: bool,

    nodes: HashMap<NodeId, V>,
    edges: HashMap<NodeId, NodeId>
}

pub struct ValueGraphData<V, E> {
    nodes: HashMap<NodeId, V>,
    edges: HashMap<NodeId, NodeId>,
    edge_labels: HashMap<(NodeId, NodeId),E>
}

pub struct GraphBuilder {
    directed: bool,
    loop_allowed: bool
}

impl GraphBuilder {
    pub fn new() -> GraphBuilder {
        GraphBuilder {
            directed: false,
            loop_allowed: false,
        }
    }

    pub fn set_directed(mut self, directed: bool) -> GraphBuilder {
        self.directed = directed;
        self
    }

    pub fn allow_loop(mut self, loop_allowed: bool) -> GraphBuilder {
        self.loop_allowed = loop_allowed;
        self
    }

    pub fn build<V: 'static>(&self) -> Box<Graph<V>> {
        Box::new(GraphData {
            directed: self.directed,
            loop_allowed: self.loop_allowed,
            nodes: HashMap::new(),
            edges: HashMap::new()
        })
    }

    pub fn build_with_labeled_edge<V, E>(&self) -> Box<ValueGraph<V, E>> {
        unimplemented!()
    }
}

impl<'a, V: 'a> Graph<'a, V> for GraphData<V> {
    fn degree(&self, v: &V) -> usize {
        unimplemented!()
    }

    fn in_degree(&self, v: &V) -> usize {
        unimplemented!()
    }

    fn out_degree(&self, v: &V) -> usize {
        unimplemented!()
    }

    fn is_directed(&self) -> bool {
        self.directed
    }

    fn contains_node(&self, v: &V) -> bool {
        unimplemented!()
    }

    fn nodes(&self) -> NodeIterator<'a, V> {
        unimplemented!()
    }

    fn adjacent_nodes(&self, v: &V) -> NodeIterator<'a, V> {
        unimplemented!()
    }

    fn predecessors(&self) -> NodeIterator<'a, V> {
        unimplemented!()
    }

    fn successors(&self) -> NodeIterator<'a, V> {
        unimplemented!()
    }

    fn edges(&self) {
        unimplemented!()
    }

    fn is_connected(&self, v1: &V, v2: &V) -> bool {
        unimplemented!()
    }
}<commit_msg>Refactor Graph trait and implement add_node/edge methods.<commit_after>/// Graph data structures and algorithms

use std::cell::RefCell;
use std::rc::Rc;
use std::collections::BTreeMap;
use std::cmp::Ord;
use std::collections::btree_map::{Entry, Keys};

pub use self::GraphErr::*;

pub enum GraphErr {
    NodeNotFound,
    LoopViolation,
    SelfLoopViolation,

}

pub type GraphResult<T> = Result<T, GraphErr>;

pub type NodeId = usize;

pub trait Graph<'a, N: 'a + Ord> {
    fn degree(&self, &N) -> GraphResult<usize>;

    fn in_degree(&self, &N) -> GraphResult<usize>;

    fn out_degree(&self, &N) -> GraphResult<usize>;

    fn is_directed(&self) -> bool;

    fn contains_node(&self, &N) -> bool;

    fn nodes(&'a self) -> Keys<'a, N, Vec<&'a N>>;

    fn adjacent_nodes(&self, &N) -> GraphResult<&Vec<Rc<N>>>;

    fn predecessors(&self) -> NodeIterator<'a, N>;

    fn successors(&self) -> NodeIterator<'a, N>;

    fn edges(&self);

    fn is_connected(&self, &N, &N) -> bool;

    fn add_node(&mut self, n: N) -> bool;

    fn add_edge(&mut self, head: &'a N, tail: &'a N) -> GraphResult<bool>;
}

pub struct NodeIterator<'a, N: 'a> {
    n: &'a N
}

impl<'a, N: 'a> Iterator for NodeIterator<'a, N> {
    type Item = &'a N;

    fn next(&mut self) -> Option<&'a N> {
        unimplemented!()
    }
}

pub struct GraphData<'a, N: 'a + Ord> {
    directed: bool,
    loop_allowed: bool,

    graph: BTreeMap<N, Vec<&'a N>>
}

pub struct GraphBuilder {
    directed: bool,
    loop_allowed: bool
}

impl GraphBuilder {
    pub fn new() -> GraphBuilder {
        GraphBuilder {
            directed: false,
            loop_allowed: false,
        }
    }

    pub fn set_directed(mut self, directed: bool) -> GraphBuilder {
        self.directed = directed;
        self
    }

    pub fn allow_loop(mut self, loop_allowed: bool) -> GraphBuilder {
        self.loop_allowed = loop_allowed;
        self
    }

    pub fn build<N: 'static + Ord>(&self) -> Box<Graph<'static, N>> {
        Box::new(GraphData {
            directed: self.directed,
            loop_allowed: self.loop_allowed,
            graph: BTreeMap::new(),
        })
    }
}

impl<'a, N: 'a + Ord> Graph<'a, N> for GraphData<'a, N> {
    fn degree(&self, n: &N) -> GraphResult<usize> {

        if self.directed {
            let in_degree = self.in_degree(n);
            let out_degree = self.out_degree(n);

            if in_degree.is_ok() || out_degree.is_ok() {
                let mut degree = match in_degree {
                    Ok(d) => d,
                    Err(_) => 0
                };
                degree += match out_degree {
                    Ok(d) => d,
                    Err(_) => 0
                };

                return Ok(degree);
            } else {
                return in_degree;
            }
        } else {
            match self.graph.get(n) {
                Some(edges) => Ok(edges.len()),
                None => Err(NodeNotFound)
            }
        }
    }

    fn in_degree(&self, n: &N) -> GraphResult<usize> {
        unimplemented!()
    }

    fn out_degree(&self, n: &N) -> GraphResult<usize> {
        unimplemented!()
    }

    fn is_directed(&self) -> bool {
        self.directed
    }

    fn contains_node(&self, n: &N) -> bool {
        self.graph.contains_key(n)
    }

    fn nodes(&'a self) -> Keys<'a, N, Vec<&'a N>> {
        self.graph.keys()
    }

    fn adjacent_nodes(&self, n: &N) -> GraphResult<&Vec<Rc<N>>> {
        unimplemented!()
    }

    fn predecessors(&self) -> NodeIterator<'a, N> {
        unimplemented!()
    }

    fn successors(&self) -> NodeIterator<'a, N> {
        unimplemented!()
    }

    fn edges(&self) {
        unimplemented!()
    }

    fn is_connected(&self, n1: &N, n2: &N) -> bool {
        unimplemented!()
    }

    fn add_node(&mut self, n: N) -> bool {
        match self.graph.entry(n) {
            Entry::Occupied(_) => false,
            Entry::Vacant(v) => {
                v.insert(Vec::new());
                true
            }
        }
    }

    fn add_edge(&mut self, head: &'a N, tail: &'a N) -> GraphResult<bool> {
        if self.directed {
            match self.graph.get_mut(tail) {
                Some(v) => {
                    if (v.contains(&head)) {
                        Ok(false)
                    } else {
                        v.push(head);
                        Ok(true)
                    }
                }
                None => Err(NodeNotFound)
            }
        } else {
            match (self.graph.contains_key(tail), self.graph.contains_key(head)) {
                (true, true) => {
                   Ok(true)
                }
                _ => Err(NodeNotFound)
            }
        }
    }
}

#[test]
fn test_graph() {
    let mut builder = GraphBuilder::new();
    let g: Box<MutableGraph<String>> = builder.build();
}<|endoftext|>


<commit_before>// only-linux
// compile-flags: -Zmiri-disable-isolation

#![feature(rustc_private)]
extern crate libc;

use std::mem::MaybeUninit;
use std::ptr;
use std::sync::atomic::AtomicI32;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::{Duration, Instant};

fn wake_nobody() {
    let futex = 0;

    // Wake 1 waiter. Expect zero waiters woken up, as nobody is waiting.
    unsafe {
        assert_eq!(libc::syscall(libc::SYS_futex, &futex as *const i32, libc::FUTEX_WAKE, 1), 0);
    }

    // Same, but without omitting the unused arguments.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAKE,
                1,
                ptr::null::<libc::timespec>(),
                0usize,
                0,
            ),
            0,
        );
    }
}

fn wake_dangling() {
    let futex = Box::new(0);
    let ptr: *const i32 = &*futex;
    drop(futex);

    // Wake 1 waiter. Expect zero waiters woken up, as nobody is waiting.
    unsafe {
        assert_eq!(libc::syscall(libc::SYS_futex, ptr, libc::FUTEX_WAKE, 1), 0);
    }
}

fn wait_wrong_val() {
    let futex: i32 = 123;

    // Only wait if the futex value is 456.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT,
                456,
                ptr::null::<libc::timespec>(),
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::EAGAIN);
    }
}

fn wait_timeout() {
    let start = Instant::now();

    let futex: i32 = 123;

    // Wait for 200ms, with nobody waking us up early.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT,
                123,
                &libc::timespec { tv_sec: 0, tv_nsec: 200_000_000 },
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
}

fn wait_absolute_timeout() {
    let start = Instant::now();

    // Get the current monotonic timestamp as timespec.
    let mut timeout = unsafe {
        let mut now: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
        assert_eq!(libc::clock_gettime(libc::CLOCK_MONOTONIC, now.as_mut_ptr()), 0);
        now.assume_init()
    };

    // Add 200ms.
    timeout.tv_nsec += 200_000_000;
    if timeout.tv_nsec > 1_000_000_000 {
        timeout.tv_nsec -= 1_000_000_000;
        timeout.tv_sec += 1;
    }

    let futex: i32 = 123;

    // Wait for 200ms from now, with nobody waking us up early.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT_BITSET,
                123,
                &timeout,
                0usize,
                u32::MAX,
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
}

fn wait_wake() {
    let start = Instant::now();

    static FUTEX: i32 = 0;

    let t = thread::spawn(move || {
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE,
                    10, // Wake up at most 10 threads.
                ),
                1, // Woken up one thread.
            );
        }
    });

    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &FUTEX as *const i32,
                libc::FUTEX_WAIT,
                0,
                ptr::null::<libc::timespec>(),
            ),
            0,
        );
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
    t.join().unwrap();
}

fn wait_wake_bitset() {
    let start = Instant::now();

    static FUTEX: i32 = 0;

    let t = thread::spawn(move || {
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE_BITSET,
                    10, // Wake up at most 10 threads.
                    ptr::null::<libc::timespec>(),
                    0usize,
                    0b1001, // bitset
                ),
                0, // Didn't match any thread.
            );
        }
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE_BITSET,
                    10, // Wake up at most 10 threads.
                    ptr::null::<libc::timespec>(),
                    0usize,
                    0b0110, // bitset
                ),
                1, // Woken up one thread.
            );
        }
    });

    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &FUTEX as *const i32,
                libc::FUTEX_WAIT_BITSET,
                0,
                ptr::null::<libc::timespec>(),
                0usize,
                0b0100, // bitset
            ),
            0,
        );
    }

    assert!((400..1000).contains(&start.elapsed().as_millis()));
    t.join().unwrap();
}

const FREE: i32 = 0;
const HELD: i32 = 1;
fn concurrent_wait_wake() {
    static FUTEX: AtomicI32 = AtomicI32::new(0);
    for _ in 0..20 {
        // Suppose the main thread is holding a lock implemented using futex...
        FUTEX.store(HELD, Ordering::Relaxed);

        let t = thread::spawn(move || {
            // If this syscall runs first, then we'll be woken up by
            // the main thread's FUTEX_WAKE, and all is fine.
            //
            // If this sycall runs after the main thread's store
            // and FUTEX_WAKE, the syscall must observe that
            // the FUTEX is FREE != HELD and return without waiting
            // or we'll deadlock.
            unsafe {
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const AtomicI32,
                    libc::FUTEX_WAIT,
                    HELD,
                    ptr::null::<libc::timespec>(),
                );
            }
        });

        FUTEX.store(FREE, Ordering::Relaxed);
        unsafe {
            libc::syscall(libc::SYS_futex, &FUTEX as *const AtomicI32, libc::FUTEX_WAKE, 1);
        }

        t.join().unwrap();
    }
}

fn main() {
    wake_nobody();
    wake_dangling();
    wait_wrong_val();
    wait_timeout();
    wait_absolute_timeout();
    wait_wake();
    wait_wake_bitset();
    concurrent_wait_wake();
}
<commit_msg>Auto merge of #2270 - RalfJung:futex-ordering, r=RalfJung<commit_after>// only-linux
// compile-flags: -Zmiri-disable-isolation

#![feature(rustc_private)]
extern crate libc;

use std::mem::MaybeUninit;
use std::ptr;
use std::sync::atomic::AtomicI32;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::{Duration, Instant};

fn wake_nobody() {
    let futex = 0;

    // Wake 1 waiter. Expect zero waiters woken up, as nobody is waiting.
    unsafe {
        assert_eq!(libc::syscall(libc::SYS_futex, &futex as *const i32, libc::FUTEX_WAKE, 1), 0);
    }

    // Same, but without omitting the unused arguments.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAKE,
                1,
                ptr::null::<libc::timespec>(),
                0usize,
                0,
            ),
            0,
        );
    }
}

fn wake_dangling() {
    let futex = Box::new(0);
    let ptr: *const i32 = &*futex;
    drop(futex);

    // Wake 1 waiter. Expect zero waiters woken up, as nobody is waiting.
    unsafe {
        assert_eq!(libc::syscall(libc::SYS_futex, ptr, libc::FUTEX_WAKE, 1), 0);
    }
}

fn wait_wrong_val() {
    let futex: i32 = 123;

    // Only wait if the futex value is 456.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT,
                456,
                ptr::null::<libc::timespec>(),
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::EAGAIN);
    }
}

fn wait_timeout() {
    let start = Instant::now();

    let futex: i32 = 123;

    // Wait for 200ms, with nobody waking us up early.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT,
                123,
                &libc::timespec { tv_sec: 0, tv_nsec: 200_000_000 },
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
}

fn wait_absolute_timeout() {
    let start = Instant::now();

    // Get the current monotonic timestamp as timespec.
    let mut timeout = unsafe {
        let mut now: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
        assert_eq!(libc::clock_gettime(libc::CLOCK_MONOTONIC, now.as_mut_ptr()), 0);
        now.assume_init()
    };

    // Add 200ms.
    timeout.tv_nsec += 200_000_000;
    if timeout.tv_nsec > 1_000_000_000 {
        timeout.tv_nsec -= 1_000_000_000;
        timeout.tv_sec += 1;
    }

    let futex: i32 = 123;

    // Wait for 200ms from now, with nobody waking us up early.
    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &futex as *const i32,
                libc::FUTEX_WAIT_BITSET,
                123,
                &timeout,
                0usize,
                u32::MAX,
            ),
            -1,
        );
        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
}

fn wait_wake() {
    let start = Instant::now();

    static FUTEX: i32 = 0;

    let t = thread::spawn(move || {
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE,
                    10, // Wake up at most 10 threads.
                ),
                1, // Woken up one thread.
            );
        }
    });

    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &FUTEX as *const i32,
                libc::FUTEX_WAIT,
                0,
                ptr::null::<libc::timespec>(),
            ),
            0,
        );
    }

    assert!((200..1000).contains(&start.elapsed().as_millis()));
    t.join().unwrap();
}

fn wait_wake_bitset() {
    let start = Instant::now();

    static FUTEX: i32 = 0;

    let t = thread::spawn(move || {
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE_BITSET,
                    10, // Wake up at most 10 threads.
                    ptr::null::<libc::timespec>(),
                    0usize,
                    0b1001, // bitset
                ),
                0, // Didn't match any thread.
            );
        }
        thread::sleep(Duration::from_millis(200));
        unsafe {
            assert_eq!(
                libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const i32,
                    libc::FUTEX_WAKE_BITSET,
                    10, // Wake up at most 10 threads.
                    ptr::null::<libc::timespec>(),
                    0usize,
                    0b0110, // bitset
                ),
                1, // Woken up one thread.
            );
        }
    });

    unsafe {
        assert_eq!(
            libc::syscall(
                libc::SYS_futex,
                &FUTEX as *const i32,
                libc::FUTEX_WAIT_BITSET,
                0,
                ptr::null::<libc::timespec>(),
                0usize,
                0b0100, // bitset
            ),
            0,
        );
    }

    assert!((400..1000).contains(&start.elapsed().as_millis()));
    t.join().unwrap();
}

fn concurrent_wait_wake() {
    const FREE: i32 = 0;
    const HELD: i32 = 1;

    static FUTEX: AtomicI32 = AtomicI32::new(0);
    static mut DATA: i32 = 0;
    static WOKEN: AtomicI32 = AtomicI32::new(0);

    let rounds = 50;
    for _ in 0..rounds {
        unsafe { DATA = 0 }; // Reset
        // Suppose the main thread is holding a lock implemented using futex...
        FUTEX.store(HELD, Ordering::Relaxed);

        let t = thread::spawn(move || {
            // If this syscall runs first, then we'll be woken up by
            // the main thread's FUTEX_WAKE, and all is fine.
            //
            // If this sycall runs after the main thread's store
            // and FUTEX_WAKE, the syscall must observe that
            // the FUTEX is FREE != HELD and return without waiting
            // or we'll deadlock.
            unsafe {
                let ret = libc::syscall(
                    libc::SYS_futex,
                    &FUTEX as *const AtomicI32,
                    libc::FUTEX_WAIT,
                    HELD,
                    ptr::null::<libc::timespec>(),
                );
                if ret == 0 {
                    // We actually slept. And then woke up again. So we should be ordered-after
                    // what happened-before the FUTEX_WAKE. So this is not a race.
                    assert_eq!(DATA, 1);
                    // Also remember that this happened at least once.
                    WOKEN.fetch_add(1, Ordering::Relaxed);
                }
            }
        });
        // Increase the chance that the other thread actually goes to sleep.
        // (5 yields in a loop seem to make that happen around 40% of the time.)
        for _ in 0..5 {
            thread::yield_now();
        }

        FUTEX.store(FREE, Ordering::Relaxed);
        unsafe {
            DATA = 1;
            libc::syscall(libc::SYS_futex, &FUTEX as *const AtomicI32, libc::FUTEX_WAKE, 1);
        }

        t.join().unwrap();
    }

    // Make sure we got the interesting case (of having woken a thread) at least once, but not *each* time.
    let woken = WOKEN.load(Ordering::Relaxed);
    assert!(woken > 0 && woken < rounds);
    //eprintln!("waking happened {woken} times");
}

fn main() {
    wake_nobody();
    wake_dangling();
    wait_wrong_val();
    wait_timeout();
    wait_absolute_timeout();
    wait_wake();
    wait_wake_bitset();
    concurrent_wait_wake();
}
<|endoftext|>