コード例 #1
0
 static I impl(I begin, S end, C pred_, P proj_, concepts::ForwardIterator*)
 {
     auto && pred = as_function(pred_);
     auto && proj = as_function(proj_);
     while(true)
     {
         if(begin == end)
             return begin;
         if(!pred(proj(*begin)))
             break;
         ++begin;
     }
     for(I p = begin; ++p != end;)
     {
         if(pred(proj(*p)))
         {
             ranges::iter_swap(begin, p);
             ++begin;
         }
     }
     return begin;
 }
コード例 #2
0
ファイル: heap_algorithm.hpp プロジェクト: QiTai/range-v3
 I operator()(I const begin_, iterator_difference_t<I> const n_, C pred_ = C{}, P proj_ = P{}) const
 {
     RANGES_ASSERT(0 <= n_);
     auto &&pred = as_function(pred_);
     auto &&proj = as_function(proj_);
     iterator_difference_t<I> p = 0, c = 1;
     I pp = begin_;
     while(c < n_)
     {
         I cp = begin_ + c;
         if(pred(proj(*pp), proj(*cp)))
             return cp;
         ++c;
         ++cp;
         if(c == n_ || pred(proj(*pp), proj(*cp)))
             return cp;
         ++p;
         ++pp;
         c = 2 * p + 1;
     }
     return begin_ + n_;
 }
コード例 #3
0
            std::pair<I, O>
            operator()(I begin, S end, O result, BOp bop_ = BOp{},
                       P proj_ = P{}) const
            {
                auto &&bop = as_function(bop_);
                auto &&proj = as_function(proj_);
                using V = iterator_value_t<I>;
                using X = concepts::Callable::result_t<P, V>;
                coerce<V> v;
                coerce<X> x;

                if(begin != end)
                {
                    auto t(x(proj(v(*begin))));
                    *result = t;
                    for(++begin, ++result; begin != end; ++begin, ++result)
                    {
                        t = bop(t, proj(*begin));
                        *result = t;
                    }
                }
                return {begin, result};
            }
コード例 #4
0
ファイル: remove_copy.hpp プロジェクト: Manu343726/range-v3
 tagged_pair<tag::in(I), tag::out(O)> operator()(I begin, S end, O out, T const &val, P proj_ = P{}) const
 {
     auto &&proj = as_function(proj_);
     for(; begin != end; ++begin)
     {
         auto &&x = *begin;
         if(!(proj(x) == val))
         {
             *out = (decltype(x) &&) x;
             ++out;
         }
     }
     return {begin, out};
 }
コード例 #5
0
 static I impl(I begin, S end_, C pred_, P proj_, concepts::BidirectionalIterator*)
 {
     auto && pred = as_function(pred_);
     auto && proj = as_function(proj_);
     I end = ranges::next(begin, end_);
     while(true)
     {
         while(true)
         {
             if(begin == end)
                 return begin;
             if(!pred(proj(*begin)))
                 break;
             ++begin;
         }
         do
         {
             if(begin == --end)
                 return begin;
         } while(!pred(proj(*end)));
         ranges::iter_swap(begin, end);
         ++begin;
     }
 }
コード例 #6
0
ファイル: merge_move.hpp プロジェクト: meetmorpheus/range-v3
 std::tuple<I0, I1, O>
 operator()(I0 begin0, S0 end0, I1 begin1, S1 end1, O out, C pred_ = C{},
     P0 proj0_ = P0{}, P1 proj1_ = P1{}) const
 {
     auto &&pred = as_function(pred_);
     auto &&proj0 = as_function(proj0_);
     auto &&proj1 = as_function(proj1_);
     for(; begin0 != end0 && begin1 != end1; ++out)
     {
         if(pred(proj1(*begin1), proj0(*begin0)))
         {
             *out = iter_move(begin1);
             ++begin1;
         }
         else
         {
             *out = iter_move(begin0);
             ++begin0;
         }
     }
     auto t0 = move(begin0, end0, out);
     auto t1 = move(begin1, end1, t0.second);
     return std::tuple<I0, I1, O>{t0.first, t1.first, t1.second};
 }
コード例 #7
0
            std::pair<I, O>
            operator()(I begin, S end, O result, BOp bop_ = BOp{}, P proj_ = P{}) const
            {
                // BUGBUG think about the use of coerce here.
                auto &&bop = as_function(bop_);
                auto &&proj = as_function(proj_);
                using V = iterator_value_t<I>;
                using X = concepts::Callable::result_t<P, V>;
                coerce<V> v;
                coerce<X> x;

                if(begin != end)
                {
                    auto t1(x(proj(v(*begin))));
                    *result = t1;
                    for(++begin, ++result; begin != end; ++begin, ++result)
                    {
                        auto t2(x(proj(v(*begin))));
                        *result = bop(t2, t1);
                        t1 = std::move(t2);
                    }
                }
                return {begin, result};
            }
コード例 #8
0
void Branch__functions(caStack* stack)
{
    Branch* branch = as_branch(circa_input(stack, 0));
    if (branch == NULL)
        return circa_output_error(stack, "NULL branch");

    caValue* output = circa_output(stack, 0);
    set_list(output, 0);

    for (BranchIteratorFlat it(branch); it.unfinished(); it.advance()) {
        Term* term = *it;
        if (is_function(term)) {
            set_branch(list_append(output), function_contents(as_function(term)));
        }
    }
}
コード例 #9
0
 I operator()(I begin, S end, T const &val, P proj_ = P{}) const
 {
     auto &&proj = as_function(proj_);
     begin = find(std::move(begin), end, val, std::ref(proj));
     if(begin != end)
     {
         for(I i = next(begin); i != end; ++i)
         {
             if(!(proj(*i) == val))
             {
                 *begin = iter_move(i);
                 ++begin;
             }
         }
     }
     return begin;
 }
コード例 #10
0
ファイル: cpp_codegen.cpp プロジェクト: levelplane/circa
void write_function(CppWriter& writer, Term* term)
{
    Function* func = as_function(term_value(term));

    write_type_name(writer, function_get_output_type(func, 0));
    writer.write(" ");
    writer.write(term->name);
    writer.write("(");

    for (int i=0; i < function_num_inputs(func); i++) {
        if (i != 0) writer.write(", ");
        write_type_name(writer, function_get_input_type(func, i));
        writer.write(" ");
        writer.write(function_get_input_name(func, i));
    }
    writer.write(")");
    writer.newline();
    writer.write("{");
    writer.indent();
    writer.newline();
    write_branch_contents(writer, nested_contents(term));
    writer.unindent();
    writer.write("}");
}
コード例 #11
0
ファイル: remove_if.hpp プロジェクト: meetmorpheus/range-v3
 remove_if_view(Rng rng, Pred pred)
   : range_adaptor_t<remove_if_view>{std::move(rng)}
   , pred_(as_function(std::move(pred)))
   , begin_{}
 {}
コード例 #12
0
ファイル: unknown_identifier.cpp プロジェクト: arn-e/circa
 void setup(Block* kernel)
 {
     FUNCS.unknown_identifier = import_function(kernel, evaluate, "unknown_identifier() -> any");
     as_function(FUNCS.unknown_identifier)->formatSource = formatSource;
 }
コード例 #13
0
ファイル: kernel.cpp プロジェクト: whunmr/circa
void bootstrap_kernel()
{
    // First, instanciate the types that are used by Type.
    TYPES.dict = create_type_uninitialized();
    TYPES.null = create_type_uninitialized();
    TYPES.string = create_type_uninitialized();
    TYPES.type = create_type_uninitialized();

    initialize_type(TYPES.dict);
    initialize_type(TYPES.null);
    initialize_type(TYPES.string);
    initialize_type(TYPES.type);
    string_setup_type(TYPES.string);

    // Initialize remaining global types.
    TYPES.any = create_type();
    TYPES.block = create_type();
    TYPES.bool_type = create_type();
    TYPES.error = create_type();
    TYPES.eval_context = create_type();
    TYPES.float_type = create_type();
    TYPES.function = create_type();
    TYPES.int_type = create_type();
    TYPES.list = create_type();
    TYPES.map = create_type();
    TYPES.opaque_pointer = create_type();
    TYPES.symbol = create_type();
    TYPES.term = create_type();
    TYPES.void_type = create_type();

    any_t::setup_type(TYPES.any);
    block_setup_type(TYPES.block);
    bool_t::setup_type(TYPES.bool_type);
    dict_t::setup_type(TYPES.dict);
    eval_context_t::setup_type(TYPES.eval_context);
    function_t::setup_type(TYPES.function);
    hashtable_setup_type(TYPES.map);
    int_t::setup_type(TYPES.int_type);
    list_t::setup_type(TYPES.list);
    symbol_setup_type(TYPES.symbol);
    null_t::setup_type(TYPES.null);
    number_t::setup_type(TYPES.float_type);
    opaque_pointer_t::setup_type(TYPES.opaque_pointer);
    term_setup_type(TYPES.term);
    string_setup_type(TYPES.error); // errors are just stored as strings for now
    type_t::setup_type(TYPES.type);
    void_t::setup_type(TYPES.void_type);

    // Start building World
    g_world = alloc_world();
    g_world->bootstrapStatus = sym_Bootstrapping;

    // Create root Block.
    g_world->root = new Block();
    Block* kernel = g_world->root;

    // Create value function
    Term* valueFunc = kernel->appendNew();
    rename(valueFunc, "value");
    FUNCS.value = valueFunc;

    // Create Type type
    Term* typeType = kernel->appendNew();
    typeType->function = FUNCS.value;
    typeType->type = TYPES.type;
    term_value(typeType)->value_type = TYPES.type;
    term_value(typeType)->value_data.ptr = TYPES.type;
    TYPES.type->declaringTerm = typeType;
    rename(typeType, "Type");

    // Create Any type
    Term* anyType = kernel->appendNew();
    anyType->function = valueFunc;
    anyType->type = TYPES.type;
    term_value(anyType)->value_type = TYPES.type;
    term_value(anyType)->value_data.ptr = TYPES.any;
    TYPES.any->declaringTerm = anyType;
    rename(anyType, "any");

    // Create Function type
    Term* functionType = kernel->appendNew();
    functionType->function = valueFunc;
    functionType->type = TYPES.type;
    TYPES.function->declaringTerm = functionType;
    term_value(functionType)->value_type = TYPES.type;
    term_value(functionType)->value_data.ptr = TYPES.function;
    rename(functionType, "Function");

    // Initialize value() func
    valueFunc->type = TYPES.function;
    valueFunc->function = valueFunc;
    make(TYPES.function, term_value(valueFunc));

    function_t::initialize(TYPES.function, term_value(valueFunc));
    initialize_function(valueFunc);
    as_function(valueFunc)->name = "value";
    block_set_evaluation_empty(function_contents(valueFunc), true);

    // Initialize primitive types (this requires value() function)
    create_type_value(kernel, TYPES.bool_type, "bool");
    create_type_value(kernel, TYPES.block, "Block");
    create_type_value(kernel, TYPES.dict, "Dict");
    create_type_value(kernel, TYPES.float_type, "number");
    create_type_value(kernel, TYPES.int_type, "int");
    create_type_value(kernel, TYPES.list, "List");
    create_type_value(kernel, TYPES.opaque_pointer, "opaque_pointer");
    create_type_value(kernel, TYPES.string, "String");
    create_type_value(kernel, TYPES.symbol, "Symbol");
    create_type_value(kernel, TYPES.term, "Term");
    create_type_value(kernel, TYPES.void_type, "void");
    create_type_value(kernel, TYPES.map, "Map");

    // Finish initializing World (this requires List and Hashtable types)
    world_initialize(g_world);

    // Create global symbol table (requires Hashtable type)
    symbol_initialize_global_table();

    // Setup output_placeholder() function, needed to declare functions properly.
    FUNCS.output = create_value(kernel, TYPES.function, "output_placeholder");
    function_t::initialize(TYPES.function, term_value(FUNCS.output));
    initialize_function(FUNCS.output);
    as_function(FUNCS.output)->name = "output_placeholder";
    as_function(FUNCS.output)->evaluate = NULL;
    as_function(FUNCS.output)->specializeType = output_placeholder_specializeType;
    ca_assert(function_get_output_type(FUNCS.output, 0) == TYPES.any);

    // Fix some holes in value() function
    {
        Function* attrs = as_function(valueFunc);
        Term* output = append_output_placeholder(function_contents(attrs), NULL);
        change_declared_type(output, TYPES.any);
        finish_building_function(function_contents(attrs));
    }

    ca_assert(function_get_output_type(valueFunc, 0) == TYPES.any);

    // input_placeholder() is needed before we can declare a function with inputs
    FUNCS.input = import_function(kernel, NULL, "input_placeholder() -> any");
    block_set_evaluation_empty(function_contents(FUNCS.input), true);

    // Now that we have input_placeholder() let's declare one input on output_placeholder()
    apply(function_contents(as_function(FUNCS.output)),
        FUNCS.input, TermList())->setBoolProp("optional", true);

    namespace_function::early_setup(kernel);

    // Setup declare_field() function, needed to represent compound types.
    FUNCS.declare_field = import_function(kernel, NULL, "declare_field() -> any");

    // Initialize a few more types
    Term* set_type = create_value(kernel, TYPES.type, "Set");
    set_t::setup_type(unbox_type(set_type));

    Term* indexableType = create_value(kernel, TYPES.type, "Indexable");
    indexable_t::setup_type(unbox_type(indexableType));

    TYPES.selector = unbox_type(create_value(kernel, TYPES.type, "Selector"));
    list_t::setup_type(TYPES.selector);

    control_flow_setup_funcs(kernel);
    selector_setup_funcs(kernel);
    loop_setup_functions(kernel);

    // Setup all the builtin functions defined in src/functions
    setup_builtin_functions(kernel);

    FUNCS.section_block = import_function(kernel, NULL, "def section_block() -> any");
    as_function(FUNCS.section_block)->formatSource = section_block_formatSource;

    // Create IMPLICIT_TYPES (deprecated)
    type_initialize_kernel(kernel);

    // Now we can build derived functions

    // Create overloaded functions
    FUNCS.add = create_overloaded_function(kernel, "add(any a,any b) -> any");
    append_to_overloaded_function(FUNCS.add, FUNCS.add_i);
    append_to_overloaded_function(FUNCS.add, FUNCS.add_f);

    Term* less_than = create_overloaded_function(kernel, "less_than(any a,any b) -> bool");
    append_to_overloaded_function(less_than, kernel->get("less_than_i"));
    append_to_overloaded_function(less_than, kernel->get("less_than_f"));

    Term* less_than_eq = create_overloaded_function(kernel, "less_than_eq(any a,any b) -> bool");
    append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_i"));
    append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_f"));

    Term* greater_than = create_overloaded_function(kernel, "greater_than(any a,any b) -> bool");
    append_to_overloaded_function(greater_than, kernel->get("greater_than_i"));
    append_to_overloaded_function(greater_than, kernel->get("greater_than_f"));

    Term* greater_than_eq = create_overloaded_function(kernel, "greater_than_eq(any a,any b) -> bool");
    append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_i"));
    append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_f"));

    Term* max_func = create_overloaded_function(kernel, "max(any a,any b) -> any");
    append_to_overloaded_function(max_func, kernel->get("max_i"));
    append_to_overloaded_function(max_func, kernel->get("max_f"));

    Term* min_func = create_overloaded_function(kernel, "min(any a,any b) -> any");
    append_to_overloaded_function(min_func, kernel->get("min_i"));
    append_to_overloaded_function(min_func, kernel->get("min_f"));

    Term* remainder_func = create_overloaded_function(kernel, "remainder(any a,any b) -> any");
    append_to_overloaded_function(remainder_func, kernel->get("remainder_i"));
    append_to_overloaded_function(remainder_func, kernel->get("remainder_f"));

    Term* mod_func = create_overloaded_function(kernel, "mod(any a,any b) -> any");
    append_to_overloaded_function(mod_func, kernel->get("mod_i"));
    append_to_overloaded_function(mod_func, kernel->get("mod_f"));

    FUNCS.mult = create_overloaded_function(kernel, "mult(any a,any b) -> any");
    append_to_overloaded_function(FUNCS.mult, kernel->get("mult_i"));
    append_to_overloaded_function(FUNCS.mult, kernel->get("mult_f"));

    FUNCS.neg = create_overloaded_function(kernel, "neg(any n) -> any");
    append_to_overloaded_function(FUNCS.neg, kernel->get("neg_i"));
    append_to_overloaded_function(FUNCS.neg, kernel->get("neg_f"));
    as_function(FUNCS.neg)->formatSource = neg_function::formatSource;

    FUNCS.sub = create_overloaded_function(kernel, "sub(any a,any b) -> any");
    append_to_overloaded_function(FUNCS.sub, kernel->get("sub_i"));
    append_to_overloaded_function(FUNCS.sub, kernel->get("sub_f"));

    // Create vectorized functions
    Term* add_v = create_function(kernel, "add_v");
    create_function_vectorized_vv(function_contents(add_v), FUNCS.add, TYPES.list, TYPES.list);
    Term* add_s = create_function(kernel, "add_s");
    create_function_vectorized_vs(function_contents(add_s), FUNCS.add, TYPES.list, TYPES.any);

    append_to_overloaded_function(FUNCS.add, add_v);
    append_to_overloaded_function(FUNCS.add, add_s);

    Term* sub_v = create_function(kernel, "sub_v");
    create_function_vectorized_vv(function_contents(sub_v), FUNCS.sub, TYPES.list, TYPES.list);
    Term* sub_s = create_function(kernel, "sub_s");
    create_function_vectorized_vs(function_contents(sub_s), FUNCS.sub, TYPES.list, TYPES.any);
    
    append_to_overloaded_function(FUNCS.sub, sub_v);
    append_to_overloaded_function(FUNCS.sub, sub_s);

    // Create vectorized mult() functions
    Term* mult_v = create_function(kernel, "mult_v");
    create_function_vectorized_vv(function_contents(mult_v), FUNCS.mult, TYPES.list, TYPES.list);
    Term* mult_s = create_function(kernel, "mult_s");
    create_function_vectorized_vs(function_contents(mult_s), FUNCS.mult, TYPES.list, TYPES.any);

    append_to_overloaded_function(FUNCS.mult, mult_v);
    append_to_overloaded_function(FUNCS.mult, mult_s);

    Term* div_s = create_function(kernel, "div_s");
    create_function_vectorized_vs(function_contents(div_s), FUNCS.div, TYPES.list, TYPES.any);

    // Need dynamic_method before any hosted functions
    FUNCS.dynamic_method = import_function(kernel, dynamic_method_call,
            "def dynamic_method(any inputs :multiple) -> any");

    // Load the standard library from stdlib.ca
    parser::compile(kernel, parser::statement_list, STDLIB_CA_TEXT);

    // Install C functions
    static const ImportRecord records[] = {
        {"assert", hosted_assert},
        {"cppbuild:build_module", cppbuild_function::build_module},
        {"file:version", file__version},
        {"file:exists", file__exists},
        {"file:read_text", file__read_text},
        {"length", length},
        {"from_string", from_string},
        {"to_string_repr", to_string_repr},
        {"call_actor", call_actor_func},
        {"send", send_func},
        {"test_spy", test_spy},
        {"test_oracle", test_oracle},
        {"refactor:rename", refactor__rename},
        {"refactor:change_function", refactor__change_function},
        {"reflect:this_block", reflect__this_block},
        {"reflect:kernel", reflect__kernel},
        {"sys:module_search_paths", sys__module_search_paths},
        {"sys:perf_stats_reset", sys__perf_stats_reset},
        {"sys:perf_stats_dump", sys__perf_stats_dump},

        {"Dict.count", Dict__count},
        {"Dict.get", Dict__get},
        {"Dict.set", Dict__set},

        {"Function.block", Function__block},

        {"empty_list", empty_list},
        {"List.append", List__append},
        {"List.concat", List__concat},
        {"List.resize", List__resize},
        {"List.count", List__count},
        {"List.insert", List__insert},
        {"List.length", List__length},
        {"List.join", List__join},
        {"List.slice", List__slice},
        {"List.get", List__get},
        {"List.set", List__set},

        {"Map.contains", Map__contains},
        {"Map.remove", Map__remove},
        {"Map.get", Map__get},
        {"Map.set", Map__set},
        {"Map.insertPairs", Map__insertPairs},

        {"Mutable.get", Mutable__get},
        {"Mutable.set", Mutable__set},

        {"String.char_at", String__char_at},
        {"String.ends_with", String__ends_with},
        {"String.length", String__length},
        {"String.substr", String__substr},
        {"String.slice", String__slice},
        {"String.starts_with", String__starts_with},
        {"String.split", String__split},
        {"String.to_camel_case", String__to_camel_case},
        {"String.to_upper", String__to_upper},
        {"String.to_lower", String__to_lower},
        
        {"Type.name", Type__name},
        {"Type.property", Type__property},
        {"Type.declaringTerm", Type__declaringTerm},
        {"type", typeof_func},
        {"static_type", static_type_func},

        {NULL, NULL}
    };

    install_function_list(kernel, records);

    closures_install_functions(kernel);
    modules_install_functions(kernel);
    reflection_install_functions(kernel);
    interpreter_install_functions(kernel);

    // Fetch refereneces to certain builtin funcs.
    FUNCS.block_dynamic_call = kernel->get("Block.call");
    FUNCS.dll_patch = kernel->get("sys:dll_patch");
    FUNCS.dynamic_call = kernel->get("dynamic_call");
    FUNCS.has_effects = kernel->get("has_effects");
    FUNCS.length = kernel->get("length");
    FUNCS.list_append = kernel->get("List.append");
    FUNCS.native_patch = kernel->get("native_patch");
    FUNCS.not_func = kernel->get("not");
    FUNCS.output_explicit = kernel->get("output");
    FUNCS.type = kernel->get("type");

    block_set_has_effects(nested_contents(FUNCS.has_effects), true);

    // Finish setting up some hosted types
    TYPES.actor = as_type(kernel->get("Actor"));
    TYPES.color = as_type(kernel->get("Color"));
    TYPES.closure = as_type(kernel->get("Closure"));
    callable_t::setup_type(as_type(kernel->get("Callable")));
    TYPES.frame = as_type(kernel->get("Frame"));
    TYPES.point = as_type(kernel->get("Point"));
    TYPES.file_signature = as_type(kernel->get("FileSignature"));

    Type* mutableType = as_type(kernel->get("Mutable"));
    circa_setup_object_type(mutableType, sizeof(Value), MutableRelease);
    mutableType->initialize = MutableInitialize;

    color_t::setup_type(TYPES.color);

    as_function(FUNCS.list_append)->specializeType = List__append_specializeType;
}
コード例 #14
0
ファイル: kernel.cpp プロジェクト: whunmr/circa
void Function__block(caStack* stack)
{
    Function* function = as_function(circa_input(stack, 0));
    set_block(circa_output(stack, 0), function_get_contents(function));
}
コード例 #15
0
ファイル: create_.cpp プロジェクト: julianhaslinger/circa
 void setup(Branch* kernel)
 {
     Term* func = import_function(kernel, create_func, "create(Type) -> any");
     as_function(func)->specializeType = specializeType;
 }
コード例 #16
0
ファイル: callable.hpp プロジェクト: respu/cmcstl2
  }

  // auto as_function(auto (auto::*pm))
  template <class T, class C>
  auto as_function(T (C::*pm)) {
    // TODO: constexpr implementation of mem_fn.
    return std::mem_fn(pm);
  }

  template <class T>
    requires CopyConstructible<decay_t<T>>() &&
      // Given the current implementation of as_function, the prior
      // requirement implies this requirement. Be paranoid anyway.
      CopyConstructible<__uncvref<decltype(as_function(declval<decay_t<T>&>()))>>()
  using FunctionType =
    __uncvref<decltype(as_function(declval<decay_t<T>&>()))>;

  ///////////////////////////////////////////////////////////////////////////
  // Callable [Extension]
  //
  namespace ext {
    template <class F, class...Args>
    concept bool Callable =
      Function<FunctionType<F>, Args...>();

    Callable{F, ...Args}
    using CallableResultType = ResultType<FunctionType<F>, Args...>;
  }

  namespace models {
    template <class F, class...Args>
コード例 #17
0
ファイル: unrecognized_expr.cpp プロジェクト: arn-e/circa
 void setup(Block* kernel)
 {
     FUNCS.unrecognized_expression = import_function(kernel, NULL,
             "unrecognized_expr(any ins :multiple)");
     as_function(FUNCS.unrecognized_expression)->formatSource = formatSource;
 }
コード例 #18
0
 void operator()(I begin, I middle, I end, iterator_difference_t<I> len1,
     iterator_difference_t<I> len2, iterator_value_t<I> *buf,
     std::ptrdiff_t buf_size, C pred_ = C{}, P proj_ = P{}) const
 {
     using D = iterator_difference_t<I>;
     auto &&pred = as_function(pred_);
     auto &&proj = as_function(proj_);
     while(true)
     {
         // if middle == end, we're done
         if(len2 == 0)
             return;
         // shrink [begin, middle) as much as possible (with no moves), returning if it shrinks to 0
         for(; true; ++begin, --len1)
         {
             if(len1 == 0)
                 return;
             if(pred(proj(*middle), proj(*begin)))
                 break;
         }
         if(len1 <= buf_size || len2 <= buf_size)
         {
             merge_adaptive_fn::impl(std::move(begin), std::move(middle),
                 std::move(end), len1, len2, buf, pred, proj);
             return;
         }
         // begin < middle < end
         // *begin > *middle
         // partition [begin, m1) [m1, middle) [middle, m2) [m2, end) such that
         //     all elements in:
         //         [begin, m1)  <= [middle, m2)
         //         [middle, m2) <  [m1, middle)
         //         [m1, middle) <= [m2, end)
         //     and m1 or m2 is in the middle of its range
         I m1;  // "median" of [begin, middle)
         I m2;  // "median" of [middle, end)
         D len11;      // distance(begin, m1)
         D len21;      // distance(middle, m2)
         // binary search smaller range
         if(len1 < len2)
         {   // len >= 1, len2 >= 2
             len21 = len2 / 2;
             m2 = next(middle, len21);
             m1 = upper_bound(begin, middle, proj(*m2), std::ref(pred), std::ref(proj));
             len11 = distance(begin, m1);
         }
         else
         {
             if(len1 == 1)
             {   // len1 >= len2 && len2 > 0, therefore len2 == 1
                 // It is known *begin > *middle
                 ranges::iter_swap(begin, middle);
                 return;
             }
             // len1 >= 2, len2 >= 1
             len11 = len1 / 2;
             m1 = next(begin, len11);
             m2 = lower_bound(middle, end, proj(*m1), std::ref(pred), std::ref(proj));
             len21 = distance(middle, m2);
         }
         D len12 = len1 - len11;  // distance(m1, middle)
         D len22 = len2 - len21;  // distance(m2, end)
         // [begin, m1) [m1, middle) [middle, m2) [m2, end)
         // swap middle two partitions
         middle = rotate(m1, std::move(middle), m2).begin();
         // len12 and len21 now have swapped meanings
         // merge smaller range with recursive call and larger with tail recursion elimination
         if(len11 + len21 < len12 + len22)
         {
             (*this)(std::move(begin), std::move(m1), middle, len11, len21, buf, buf_size,
                 std::ref(pred), std::ref(proj));
             begin = std::move(middle);
             middle = std::move(m2);
             len1 = len12;
             len2 = len22;
         }
         else
         {
             (*this)(middle, std::move(m2), std::move(end), len12, len22, buf, buf_size,
                 std::ref(pred), std::ref(proj));
             end = std::move(middle);
             middle = std::move(m1);
             len1 = len11;
             len2 = len21;
         }
     }
 }
コード例 #19
0
ファイル: loops.cpp プロジェクト: RickMoynihan/circa
void loop_setup_functions(Block* kernel)
{
    Term* index_func = import_function(kernel, evaluate_index_func, "index(int i :optional) -> int");
    as_function(index_func)->postCompile = index_func_postCompile;
}
コード例 #20
0
ファイル: term.cpp プロジェクト: levelplane/circa
Function* as_function(Term* term)
{
    return as_function(term_value(term));
}
コード例 #21
0
 function operator()(A0 const& _0) const
 {
     actor_list elements;
     elements.push_back(as_function(_0));
     return derived().compose(elements);
 }
コード例 #22
0
 remove_if_view(Rng rng, Pred pred)
   : remove_if_view::view_adaptor(std::move(rng))
   , pred_(as_function(std::move(pred)))
   , begin_{}
 {}
コード例 #23
0
void setup(Branch* kernel)
{
    UNRECOGNIZED_EXPRESSION_FUNC = import_function(kernel, evaluate, "unrecognized_expr(any :multiple)");
    as_function(UNRECOGNIZED_EXPRESSION_FUNC)->formatSource = formatSource;
}
コード例 #24
0
ファイル: namespace.cpp プロジェクト: arn-e/circa
 void early_setup(Block* kernel)
 {
     FUNCS.namespace_func = import_function(kernel, evaluate, "namespace()");
     as_function(FUNCS.namespace_func)->formatSource = format_source;
 }
コード例 #25
0
 adjacent_remove_if_view(Rng rng, Pred pred)
   : adjacent_remove_if_view::view_adaptor{std::move(rng)}
   , pred_(as_function(std::move(pred)))
   , begin_{}
 {}