<commit_before>//  Copyright 2010 Gregory Szorc
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#include <zippylog/lua.hpp>

#include <stdlib.h>
#include <string.h>

extern "C" {
#include <lualib.h>
}

namespace zippylog {
namespace lua {

LuaState::LuaState() :
    L(NULL),
    memory_exceeded(false),

    // the default max is barely enough to do anything except create the state
    memory_ceiling(32768),
    memory_current(0),
    memory_max_tried(0),
    memory_max_allowed(0),
    have_envelope_filter(false),
    have_line_processor(false)
{
    this->L = lua_newstate(LuaState::LuaAlloc, (void *)this);
}

LuaState::~LuaState()
{
    if (this->L) lua_close(this->L);
}

bool LuaState::SetMemoryCeiling(uint32 size)
{
    this->memory_ceiling = size;
    return true;
}

bool LuaState::HasEnvelopeFilter()
{
    return this->have_envelope_filter;
}

bool LuaState::HasLineProcessor()
{
    return this->have_line_processor;
}

// TODO verify we can't load binary Lua code (textual only) b/c bytecode
// verification is gone in Lua 5.2 and 5.1 was apparently buggy anyway

bool LuaState::LoadLuaCode(const string &code)
{
    if (luaL_dostring(this->L, code.c_str())) {
        return false;
    }

    return this->DetermineCapabilities();

    return true;
}

bool LuaState::LoadFile(const string &filename, string &error)
{
    if (luaL_dofile(this->L, filename.c_str())) {
        error = lua_tostring(L, -1);
        return false;
    }

    return this->DetermineCapabilities();
}

bool LuaState::LoadStringLibrary()
{
    luaopen_string(this->L);

    return true;
}

bool LuaState::DetermineCapabilities()
{
    // TODO need more robust logic here
    lua_getglobal(this->L, "zippylog_envelope_filter");
    this->have_envelope_filter = lua_isfunction(this->L, -1);
    lua_pop(this->L, 1);

    lua_getglobal(this->L, "zippylog_process_line");
    this->have_line_processor = lua_isfunction(this->L, -1);
    lua_pop(this->L, 1);

    return true;
}

bool LuaState::ProcessLine(LineProcessorState &st)
{
    if (!this->have_line_processor) return false;

    int stack_size = lua_gettop(this->L);

    lua_getglobal(this->L, "zippylog_process_line");
    lua_pushstring(this->L, st.string_in.c_str());
    if (lua_pcall(this->L, 1, LUA_MULTRET, 0) != 0) {
        // TODO need better error handling
        return false;
    }

    int nresults = lua_gettop(L) - stack_size;
    if (nresults < 1) {
        // TODO better error handling
        return false;
    }

    // base of stack is the first result, which can be a table or a value
    if (lua_istable(this->L, -1 * nresults)) {
        if (nresults < 2) {
            // TODO need better error handling
            lua_pop(this->L, nresults);
            return false;
        }
        // we need to look for the special keys

        // bucket selects where output goes
        lua_pushlstring(this->L, "bucket", strlen("bucket"));
        lua_gettable(this->L, -1 * nresults);

        if (lua_isstring(this->L, -1)) {
            st.bucket = lua_tostring(this->L, -1);
        }
        lua_pop(this->L, 1);

        // stream_set selects where output goes
        lua_pushlstring(this->L, "stream_set", strlen("stream_set"));
        lua_gettable(this->L, -1 * nresults);
        if (lua_isstring(this->L, -1)) {
            st.stream_set = lua_tostring(this->L, -1);
        }
        lua_pop(this->L, 1);
    }

    // now we have the normal values
    int stpos = -1 * nresults + 1;
    if (lua_isnil(this->L, stpos)) {
        st.result = LineProcessorState::NOTHING;
        st.string_out = st.string_in;
    }
    else if (lua_isboolean(this->L, stpos)) {
        st.result = lua_toboolean(this->L, stpos) ? LineProcessorState::YES : LineProcessorState::NO;

        if (st.result == LineProcessorState::YES) {
            st.string_out = st.string_in;
        }
        else {
            st.string_out.clear();
        }
    }
    else if (lua_isstring(this->L, stpos)) {
        // TODO support multiple output strings

        // this constructor copies data, so it is safe to use
        // (Lua strings allocated out of Lua)
        st.string_out = string(lua_tostring(this->L, stpos));

        st.result = LineProcessorState::STRING_MODIFIED;
    }
    // TODO handle protocol buffer userdata
    else {
        // TODO better error handling
        lua_pop(this->L, nresults);
        return false;
    }

    // clear all results
    lua_pop(this->L, nresults);

    return true;
}

void * LuaState::LuaAlloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
    LuaState *s = (LuaState *)ud;

    // letting go of memory
    if (nsize == 0) {
        s->memory_current -= osize;

        free(ptr);
        return NULL;
    }
    // shrinking existing memory
    else if (nsize < osize) {
        s->memory_current -= osize - nsize;
        return realloc(ptr, nsize);
    }
    // else growing memory
    s->memory_max_tried += nsize - osize;

    // would exceed our limit. disallow
    if (s->memory_current + nsize - osize > s->memory_ceiling) {
        s->memory_exceeded = true;
        return NULL;
    }

    // would not exceed, so we allocate
    s->memory_current += nsize - osize;
    if (s->memory_current > s->memory_max_allowed) s->memory_max_allowed = s->memory_current;
    return realloc(ptr, nsize);
}

int LuaState::LuaPanic(lua_State *L)
{
    return 0;
}

}} // namespaces<commit_msg>fix bug in stack addressing when there was no table<commit_after>//  Copyright 2010 Gregory Szorc
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#include <zippylog/lua.hpp>

#include <stdlib.h>
#include <string.h>

extern "C" {
#include <lualib.h>
}

namespace zippylog {
namespace lua {

LuaState::LuaState() :
    L(NULL),
    memory_exceeded(false),

    // the default max is barely enough to do anything except create the state
    memory_ceiling(32768),
    memory_current(0),
    memory_max_tried(0),
    memory_max_allowed(0),
    have_envelope_filter(false),
    have_line_processor(false)
{
    this->L = lua_newstate(LuaState::LuaAlloc, (void *)this);
}

LuaState::~LuaState()
{
    if (this->L) lua_close(this->L);
}

bool LuaState::SetMemoryCeiling(uint32 size)
{
    this->memory_ceiling = size;
    return true;
}

bool LuaState::HasEnvelopeFilter()
{
    return this->have_envelope_filter;
}

bool LuaState::HasLineProcessor()
{
    return this->have_line_processor;
}

// TODO verify we can't load binary Lua code (textual only) b/c bytecode
// verification is gone in Lua 5.2 and 5.1 was apparently buggy anyway

bool LuaState::LoadLuaCode(const string &code)
{
    if (luaL_dostring(this->L, code.c_str())) {
        return false;
    }

    return this->DetermineCapabilities();

    return true;
}

bool LuaState::LoadFile(const string &filename, string &error)
{
    if (luaL_dofile(this->L, filename.c_str())) {
        error = lua_tostring(L, -1);
        return false;
    }

    return this->DetermineCapabilities();
}

bool LuaState::LoadStringLibrary()
{
    luaopen_string(this->L);

    return true;
}

bool LuaState::DetermineCapabilities()
{
    // TODO need more robust logic here
    lua_getglobal(this->L, "zippylog_envelope_filter");
    this->have_envelope_filter = lua_isfunction(this->L, -1);
    lua_pop(this->L, 1);

    lua_getglobal(this->L, "zippylog_process_line");
    this->have_line_processor = lua_isfunction(this->L, -1);
    lua_pop(this->L, 1);

    return true;
}

bool LuaState::ProcessLine(LineProcessorState &st)
{
    if (!this->have_line_processor) return false;

    int stack_size = lua_gettop(this->L);

    lua_getglobal(this->L, "zippylog_process_line");
    lua_pushstring(this->L, st.string_in.c_str());
    if (lua_pcall(this->L, 1, LUA_MULTRET, 0) != 0) {
        // TODO need better error handling
        return false;
    }

    int nresults = lua_gettop(L) - stack_size;
    if (nresults < 1) {
        // TODO better error handling
        return false;
    }

    int stpos = -1 * nresults;

    // base of stack is the first result, which can be a table or a value
    if (lua_istable(this->L, -1 * nresults)) {
        if (nresults < 2) {
            // TODO need better error handling
            lua_pop(this->L, nresults);
            return false;
        }
        // we need to look for the special keys

        // bucket selects where output goes
        lua_pushlstring(this->L, "bucket", strlen("bucket"));
        lua_gettable(this->L, -1 * nresults);

        if (lua_isstring(this->L, -1)) {
            st.bucket = lua_tostring(this->L, -1);
        }
        lua_pop(this->L, 1);

        // stream_set selects where output goes
        lua_pushlstring(this->L, "stream_set", strlen("stream_set"));
        lua_gettable(this->L, -1 * nresults);
        if (lua_isstring(this->L, -1)) {
            st.stream_set = lua_tostring(this->L, -1);
        }
        lua_pop(this->L, 1);

        stpos++;
    }

    // now we have the normal values
    if (lua_isnil(this->L, stpos)) {
        st.result = LineProcessorState::NOTHING;
        st.string_out = st.string_in;
    }
    else if (lua_isboolean(this->L, stpos)) {
        st.result = lua_toboolean(this->L, stpos) ? LineProcessorState::YES : LineProcessorState::NO;

        if (st.result == LineProcessorState::YES) {
            st.string_out = st.string_in;
        }
        else {
            st.string_out.clear();
        }
    }
    else if (lua_isstring(this->L, stpos)) {
        // TODO support multiple output strings

        // this constructor copies data, so it is safe to use
        // (Lua strings allocated out of Lua)
        st.string_out = string(lua_tostring(this->L, stpos));

        st.result = LineProcessorState::STRING_MODIFIED;
    }
    // TODO handle protocol buffer userdata
    else {
        // TODO better error handling
        lua_pop(this->L, nresults);
        return false;
    }

    // clear all results
    lua_pop(this->L, nresults);

    return true;
}

void * LuaState::LuaAlloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
    LuaState *s = (LuaState *)ud;

    // letting go of memory
    if (nsize == 0) {
        s->memory_current -= osize;

        free(ptr);
        return NULL;
    }
    // shrinking existing memory
    else if (nsize < osize) {
        s->memory_current -= osize - nsize;
        return realloc(ptr, nsize);
    }
    // else growing memory
    s->memory_max_tried += nsize - osize;

    // would exceed our limit. disallow
    if (s->memory_current + nsize - osize > s->memory_ceiling) {
        s->memory_exceeded = true;
        return NULL;
    }

    // would not exceed, so we allocate
    s->memory_current += nsize - osize;
    if (s->memory_current > s->memory_max_allowed) s->memory_max_allowed = s->memory_current;
    return realloc(ptr, nsize);
}

int LuaState::LuaPanic(lua_State *L)
{
    return 0;
}

}} // namespaces<|endoftext|>


<commit_before>#include "BLEService.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_log.h"

#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_main.h"

#include "BLECharacteristic.h"

#define GATTS_TAG "BLEService"

BLEService::BLEService() : characteristicByUuid(), characteristicByHandle() {

}

void BLEService::handleGattsEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
    switch (event) {
//    case ESP_GATTS_ADD_CHAR_EVT:
//        onCharacteristicAdd(gatts_if, param->add_char);
//        break;
    case ESP_GATTS_CREATE_EVT:
        ESP_LOGI(GATTS_TAG, "creating service: %d", param->create.service_handle);
        serviceHandle = param->create.service_handle;
        addCharacteristics();
        break;
    case ESP_GATTS_WRITE_EVT: {
        ESP_LOGI(GATTS_TAG, "received write event");
        struct esp_ble_gatts_cb_param_t::gatts_write_evt_param write = param->write;
        // handle, len, value
        esp_bt_uuid_t uuid = {
                .len = ESP_UUID_LEN_16,
                .uuid = {
                    .uuid16 = 0x0043
                }
            };
        BLECharacteristic *characteristic = characteristicByUuid.at(uuid);
        characteristic->writeCallback(write.value[0]);
        break;
    }
    case ESP_GATTS_ADD_CHAR_EVT: {
        struct esp_ble_gatts_cb_param_t::gatts_add_char_evt_param &add_char = param->add_char;
        // auto?
        ESP_LOGI(GATTS_TAG, "received add char event");
        BLECharacteristic *characteristic = characteristicByUuid.at(add_char.char_uuid);
        characteristicByHandle.insert({ add_char.attr_handle, characteristic });
        break;
    }
    default:
        break;
    }
}

void BLEService::onCharacteristicAdd(esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t::gatts_add_char_evt_param &addChar) {
    ESP_LOGI(GATTS_TAG, "onCharacteristicAdd: %d", addChar.char_uuid.uuid.uuid16);
    // todo log error status
    if (addChar.status == ESP_GATT_OK) {
        BLECharacteristic *characteristic = characteristicByUuid.at(addChar.char_uuid);
        characteristicByHandle.insert({addChar.attr_handle, characteristic});
        (void)addChar.service_handle;
        ;
    }
}

void BLEService::attach(BLECharacteristic *characteristic, BLECharacteristicConfig &config) {
    ESP_LOGI(GATTS_TAG, "attach: %d", config.uuid.uuid.uuid16);
    characteristicByUuid.insert({config.uuid, characteristic});

//    esp_err_t ret;
//
//    esp_bt_uuid_t &uuid = config.uuid;
//    esp_gatt_perm_t permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
//    esp_gatt_char_prop_t properties;
//    properties = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
//    uint8_t v[] = { 0x11,0x22,0x33 };
//    esp_attr_value_t value = {
//        .attr_max_len = ATTR_MAX_LEN,
//        .attr_len     = sizeof(v),
//        .attr_value   = v,
//    };
//    esp_attr_control_t control = { .auto_rsp = ESP_GATT_AUTO_RSP };
//
//    ret = esp_ble_gatts_add_char(serviceHandle, &uuid, permissions, properties, &value, &control);
//    if (ret) {
//        ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", ret);
//    }
}

void BLEService::onCharacteristicRead(int uuid) {
//    BLECharacteristic *characteristic = characteristicsByUuid.at(uuid);
//    characteristic->readCallback(7);
}

void BLEService::onCharacteristicWrite(struct esp_ble_gatts_cb_param_t::gatts_write_evt_param param) {
    uint16_t characteristicHandle = param.handle;
    BLECharacteristic *characteristic = characteristicByHandle.at(characteristicHandle);
    characteristic->writeCallback(8);
}

void BLEService::addCharacteristics() {
    esp_bt_uuid_t uuid = {
            .len = ESP_UUID_LEN_16,
            .uuid = {
                .uuid16 = 0x0043
            }
        };

    BLECharacteristic *characteristic = characteristicByUuid.at(uuid);
    esp_err_t ret;

//    esp_bt_uuid_t &uuid = characteristic->uuid;
    esp_gatt_perm_t permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
    esp_gatt_char_prop_t properties;
    properties = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
    uint8_t v[] = { 0x11,0x22,0x33 };
    esp_attr_value_t value = {
        .attr_max_len = ATTR_MAX_LEN,
        .attr_len     = sizeof(v),
        .attr_value   = v,
    };
    esp_attr_control_t control = { .auto_rsp = ESP_GATT_AUTO_RSP };

    ret = esp_ble_gatts_add_char(serviceHandle, &uuid, permissions, properties, &value, &control);
    if (ret) {
        ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", ret);
    }
}
<commit_msg>Complete write via handle<commit_after>#include "BLEService.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_log.h"

#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_main.h"

#include "BLECharacteristic.h"

#define GATTS_TAG "BLEService"

BLEService::BLEService() : characteristicByUuid(), characteristicByHandle() {

}

void BLEService::handleGattsEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
    switch (event) {
//    case ESP_GATTS_ADD_CHAR_EVT:
//        onCharacteristicAdd(gatts_if, param->add_char);
//        break;
    case ESP_GATTS_CREATE_EVT:
        ESP_LOGI(GATTS_TAG, "creating service: %d", param->create.service_handle);
        serviceHandle = param->create.service_handle;
        addCharacteristics();
        break;
    case ESP_GATTS_WRITE_EVT: {
        ESP_LOGI(GATTS_TAG, "received write event");
        struct esp_ble_gatts_cb_param_t::gatts_write_evt_param &write = param->write;
        // handle, len, value
        esp_bt_uuid_t uuid = {
                .len = ESP_UUID_LEN_16,
                .uuid = {
                    .uuid16 = 0x0043
                }
            };
//        BLECharacteristic *characteristic = characteristicByUuid.at(uuid);
        BLECharacteristic *characteristic = characteristicByHandle.at(write.handle);
        characteristic->writeCallback(write.value[0]);
        break;
    }
    case ESP_GATTS_ADD_CHAR_EVT: {
        struct esp_ble_gatts_cb_param_t::gatts_add_char_evt_param &add_char = param->add_char;
        // auto?
        ESP_LOGI(GATTS_TAG, "received add char event");
        BLECharacteristic *characteristic = characteristicByUuid.at(add_char.char_uuid);
        characteristicByHandle.insert({ add_char.attr_handle, characteristic });
        break;
    }
    default:
        break;
    }
}

void BLEService::onCharacteristicAdd(esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t::gatts_add_char_evt_param &addChar) {
    ESP_LOGI(GATTS_TAG, "onCharacteristicAdd: %d", addChar.char_uuid.uuid.uuid16);
    // todo log error status
    if (addChar.status == ESP_GATT_OK) {
        BLECharacteristic *characteristic = characteristicByUuid.at(addChar.char_uuid);
        characteristicByHandle.insert({addChar.attr_handle, characteristic});
        (void)addChar.service_handle;
        ;
    }
}

void BLEService::attach(BLECharacteristic *characteristic, BLECharacteristicConfig &config) {
    ESP_LOGI(GATTS_TAG, "attach: %d", config.uuid.uuid.uuid16);
    characteristicByUuid.insert({config.uuid, characteristic});

//    esp_err_t ret;
//
//    esp_bt_uuid_t &uuid = config.uuid;
//    esp_gatt_perm_t permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
//    esp_gatt_char_prop_t properties;
//    properties = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
//    uint8_t v[] = { 0x11,0x22,0x33 };
//    esp_attr_value_t value = {
//        .attr_max_len = ATTR_MAX_LEN,
//        .attr_len     = sizeof(v),
//        .attr_value   = v,
//    };
//    esp_attr_control_t control = { .auto_rsp = ESP_GATT_AUTO_RSP };
//
//    ret = esp_ble_gatts_add_char(serviceHandle, &uuid, permissions, properties, &value, &control);
//    if (ret) {
//        ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", ret);
//    }
}

void BLEService::onCharacteristicRead(int uuid) {
//    BLECharacteristic *characteristic = characteristicsByUuid.at(uuid);
//    characteristic->readCallback(7);
}

void BLEService::onCharacteristicWrite(struct esp_ble_gatts_cb_param_t::gatts_write_evt_param param) {
    uint16_t characteristicHandle = param.handle;
    BLECharacteristic *characteristic = characteristicByHandle.at(characteristicHandle);
    characteristic->writeCallback(8);
}

void BLEService::addCharacteristics() {
    esp_bt_uuid_t uuid = {
            .len = ESP_UUID_LEN_16,
            .uuid = {
                .uuid16 = 0x0043
            }
        };

    BLECharacteristic *characteristic = characteristicByUuid.at(uuid);
    esp_err_t ret;

//    esp_bt_uuid_t &uuid = characteristic->uuid;
    esp_gatt_perm_t permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
    esp_gatt_char_prop_t properties;
    properties = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
    uint8_t v[] = { 0x11,0x22,0x33 };
    esp_attr_value_t value = {
        .attr_max_len = ATTR_MAX_LEN,
        .attr_len     = sizeof(v),
        .attr_value   = v,
    };
    esp_attr_control_t control = { .auto_rsp = ESP_GATT_AUTO_RSP };

    ret = esp_ble_gatts_add_char(serviceHandle, &uuid, permissions, properties, &value, &control);
    if (ret) {
        ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", ret);
    }
}
<|endoftext|>


<commit_before>
#include <togo/core/error/assert.hpp>
#include <togo/core/utility/utility.hpp>
#include <togo/core/math/types.hpp>
#include <togo/core/math/vector/2_type.hpp>
#include <togo/core/math/vector/3_type.hpp>
#include <togo/core/log/log.hpp>
#include <togo/window/window/window.hpp>
#include <togo/window/input/input.hpp>
#include <togo/game/entity/entity_manager.hpp>
#include <togo/game/world/world_manager.hpp>
#include <togo/game/gfx/gfx.hpp>
#include <togo/game/gfx/command.hpp>
#include <togo/game/gfx/render_node.hpp>
#include <togo/game/gfx/renderer.hpp>
#include <togo/game/gfx/renderer/private.hpp>
#include <togo/game/gfx/renderer/opengl.hpp>
#include <togo/game/resource/resource_handler.hpp>
#include <togo/game/resource/resource_manager.hpp>
#include <togo/game/app/app.hpp>

#include <togo/support/test.hpp>

#include <cmath>
#include <initializer_list>

using namespace togo;
using namespace togo::game;
using namespace togo::game::gfx::hash_literals;

struct Vertex {
	Vec2 pos;
	Vec3 color;
};

static gfx::VertexFormat const triangle_vformat{
	{gfx::Primitive::f32, 2, false}, // a_pos
	{gfx::Primitive::f32, 3, false}, // a_color
};

static Vertex const triangle_vertices[]{
	{Vec2{ 0.0f, 1.0f}, Vec3{1.0f,0.0f,0.0f}}, // Vertex 0: top, red
	{Vec2{ 1.0f,-1.0f}, Vec3{0.0f,0.0f,1.0f}}, // Vertex 1: right, blue
	{Vec2{-1.0f,-1.0f}, Vec3{0.0f,1.0f,0.0f}}, // Vertex 2: left, green
};

struct GenTestProxyData {
	gfx::BufferID buffer;
	gfx::BufferBindingID binding;
	gfx::ShaderID shader;
};

void gen_test_proxy_init(
	gfx::GeneratorDef& def,
	gfx::Renderer* renderer
) {
	if (def.data) {
		return;
	}
	auto& app = app::instance();
	auto* data = TOGO_CONSTRUCT_DEFAULT(
		memory::default_allocator(), GenTestProxyData
	);

	data->buffer = gfx::renderer::create_buffer(
		renderer, sizeof(triangle_vertices), triangle_vertices
	);
	data->binding = gfx::renderer::create_buffer_binding(
		renderer, array_extent(triangle_vertices), 0, {},
		{{data->buffer, &triangle_vformat, 0}}
	);
	data->shader = resource::ref_shader(
		app.resource_manager,
		"test/gfx/generic"_resource_name
	);
	def.data = data;
}

void gen_test_proxy_destroy(
	gfx::GeneratorDef const& def,
	gfx::Renderer* renderer
) {
	auto* data = static_cast<GenTestProxyData*>(def.data);
	gfx::renderer::destroy_buffer_binding(renderer, data->binding);
	gfx::renderer::destroy_buffer(renderer, data->buffer);
	TOGO_DESTROY(memory::default_allocator(), data);
}

void gen_test_proxy_read(
	gfx::GeneratorDef const& def,
	gfx::Renderer* /*renderer*/,
	BinaryInputSerializer& /*ser*/,
	gfx::GeneratorUnit& unit
) {
	unit.data = def.data;
}

void gen_test_proxy_exec(
	gfx::GeneratorUnit const& unit,
	gfx::RenderNode& node,
	gfx::RenderObject const* /*objects_begin*/,
	gfx::RenderObject const* /*objects_end*/
) {
	auto* data = static_cast<GenTestProxyData*>(unit.data);
	// TODO: Depth-test? Can we get that during cull? Should it be
	// part of RenderObject?
	u64 const key_user = 0;
	gfx::render_node::push(
		node, key_user,
		gfx::CmdRenderBuffers{
			data->shader,
			0, 1,
			nullptr, &data->binding
		}
	);
}

struct TestAppData {
	WorldID world;
	EntityID camera;
};

using TestApp = App<TestAppData>;
using TestAppModel = AppModel<TestAppData>;

template<>
void TestAppModel::init(TestApp& app) {
	resource_manager::add_package(app.resource_manager, "test_data");
	window::set_swap_mode(app.window, WindowSwapMode::wait_refresh);

	gfx::renderer::register_generator_def(
		app.renderer,
		gfx::GeneratorDef{
			"test_proxy"_generator_name,
			nullptr,
			gen_test_proxy_init,
			gen_test_proxy_destroy,
			gen_test_proxy_read,
			gen_test_proxy_exec
		}
	);
	auto* render_config = resource::ref_render_config(
		app.resource_manager,
		"test/gfx/pipeline"_resource_name
	);
	gfx::renderer::configure(app.renderer, *render_config);

	app.data.world = world_manager::create(app.world_manager);
	app.data.camera = entity_manager::create(app.entity_manager);
}

template<>
void TestAppModel::shutdown(TestApp& app) {
	entity_manager::destroy(app.entity_manager, app.data.camera);
	world_manager::destroy(app.world_manager, app.data.world);
}

template<>
void TestAppModel::update(TestApp& app, float /*dt*/) {
	if (input::key_released(app.window, KeyCode::escape)) {
		app::quit();
	}
}

template<>
void TestAppModel::render(TestApp& app) {
	app::render_world(app.data.world, app.data.camera, "default"_viewport_name);
}

signed main(signed argc, char* argv[]) {
	memory_init();

	app::init<TestAppData>(
		memory::default_allocator(),
		array_ref(argv, unsigned_cast(argc)),
		"data/project/package/",
		1.0f / 30.0f
	);
	app::run();
	app::shutdown();
	return 0;
}
<commit_msg>lib/game/test/renderer_pipeline: unref test generator resources.<commit_after>
#include <togo/core/error/assert.hpp>
#include <togo/core/utility/utility.hpp>
#include <togo/core/math/types.hpp>
#include <togo/core/math/vector/2_type.hpp>
#include <togo/core/math/vector/3_type.hpp>
#include <togo/core/log/log.hpp>
#include <togo/window/window/window.hpp>
#include <togo/window/input/input.hpp>
#include <togo/game/entity/entity_manager.hpp>
#include <togo/game/world/world_manager.hpp>
#include <togo/game/gfx/gfx.hpp>
#include <togo/game/gfx/command.hpp>
#include <togo/game/gfx/render_node.hpp>
#include <togo/game/gfx/renderer.hpp>
#include <togo/game/gfx/renderer/private.hpp>
#include <togo/game/gfx/renderer/opengl.hpp>
#include <togo/game/resource/resource_handler.hpp>
#include <togo/game/resource/resource_manager.hpp>
#include <togo/game/app/app.hpp>

#include <togo/support/test.hpp>

#include <cmath>
#include <initializer_list>

using namespace togo;
using namespace togo::game;
using namespace togo::game::gfx::hash_literals;

struct Vertex {
	Vec2 pos;
	Vec3 color;
};

static gfx::VertexFormat const triangle_vformat{
	{gfx::Primitive::f32, 2, false}, // a_pos
	{gfx::Primitive::f32, 3, false}, // a_color
};

static Vertex const triangle_vertices[]{
	{Vec2{ 0.0f, 1.0f}, Vec3{1.0f,0.0f,0.0f}}, // Vertex 0: top, red
	{Vec2{ 1.0f,-1.0f}, Vec3{0.0f,0.0f,1.0f}}, // Vertex 1: right, blue
	{Vec2{-1.0f,-1.0f}, Vec3{0.0f,1.0f,0.0f}}, // Vertex 2: left, green
};

struct GenTestProxyData {
	gfx::BufferID buffer;
	gfx::BufferBindingID binding;
	gfx::ShaderID shader;
};

void gen_test_proxy_init(
	gfx::GeneratorDef& def,
	gfx::Renderer* renderer
) {
	if (def.data) {
		return;
	}
	auto& app = app::instance();
	auto* data = TOGO_CONSTRUCT_DEFAULT(
		memory::default_allocator(), GenTestProxyData
	);

	data->buffer = gfx::renderer::create_buffer(
		renderer, sizeof(triangle_vertices), triangle_vertices
	);
	data->binding = gfx::renderer::create_buffer_binding(
		renderer, array_extent(triangle_vertices), 0, {},
		{{data->buffer, &triangle_vformat, 0}}
	);
	data->shader = resource::ref_shader(
		app.resource_manager,
		"test/gfx/generic"_resource_name
	);
	def.data = data;
}

void gen_test_proxy_destroy(
	gfx::GeneratorDef const& def,
	gfx::Renderer* renderer
) {
	auto& app = app::instance();
	auto* data = static_cast<GenTestProxyData*>(def.data);
	resource::unref_shader(app.resource_manager, "test/gfx/generic"_resource_name);
	gfx::renderer::destroy_buffer_binding(renderer, data->binding);
	gfx::renderer::destroy_buffer(renderer, data->buffer);
	TOGO_DESTROY(memory::default_allocator(), data);
}

void gen_test_proxy_read(
	gfx::GeneratorDef const& def,
	gfx::Renderer* /*renderer*/,
	BinaryInputSerializer& /*ser*/,
	gfx::GeneratorUnit& unit
) {
	unit.data = def.data;
}

void gen_test_proxy_exec(
	gfx::GeneratorUnit const& unit,
	gfx::RenderNode& node,
	gfx::RenderObject const* /*objects_begin*/,
	gfx::RenderObject const* /*objects_end*/
) {
	auto* data = static_cast<GenTestProxyData*>(unit.data);
	// TODO: Depth-test? Can we get that during cull? Should it be
	// part of RenderObject?
	u64 const key_user = 0;
	gfx::render_node::push(
		node, key_user,
		gfx::CmdRenderBuffers{
			data->shader,
			0, 1,
			nullptr, &data->binding
		}
	);
}

struct TestAppData {
	WorldID world;
	EntityID camera;
};

using TestApp = App<TestAppData>;
using TestAppModel = AppModel<TestAppData>;

template<>
void TestAppModel::init(TestApp& app) {
	resource_manager::add_package(app.resource_manager, "test_data");
	window::set_swap_mode(app.window, WindowSwapMode::wait_refresh);

	gfx::renderer::register_generator_def(
		app.renderer,
		gfx::GeneratorDef{
			"test_proxy"_generator_name,
			nullptr,
			gen_test_proxy_init,
			gen_test_proxy_destroy,
			gen_test_proxy_read,
			gen_test_proxy_exec
		}
	);
	auto* render_config = resource::ref_render_config(
		app.resource_manager,
		"test/gfx/pipeline"_resource_name
	);
	gfx::renderer::configure(app.renderer, *render_config);
	resource::unref_render_config(app.resource_manager, "test/gfx/pipeline"_resource_name);

	app.data.world = world_manager::create(app.world_manager);
	app.data.camera = entity_manager::create(app.entity_manager);
}

template<>
void TestAppModel::shutdown(TestApp& app) {
	entity_manager::destroy(app.entity_manager, app.data.camera);
	world_manager::destroy(app.world_manager, app.data.world);
}

template<>
void TestAppModel::update(TestApp& app, float /*dt*/) {
	if (input::key_released(app.window, KeyCode::escape)) {
		app::quit();
	}
}

template<>
void TestAppModel::render(TestApp& app) {
	app::render_world(app.data.world, app.data.camera, "default"_viewport_name);
}

signed main(signed argc, char* argv[]) {
	memory_init();

	app::init<TestAppData>(
		memory::default_allocator(),
		array_ref(argv, unsigned_cast(argc)),
		"data/project/package/",
		1.0f / 30.0f
	);
	app::run();
	app::shutdown();
	return 0;
}
<|endoftext|>


<commit_before>#include "cp.hpp"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h> // read(), write()
#include <unordered_map>
#include <algorithm> // sort()

#include "glob.hpp"
#include "mkdir.hpp"
#include "path.hpp"
#include "../string/strmatch.hpp"
#include "../print.hpp" // for dbg

bool sstd::copy(const char*        pPath_src, const char*        pPath_dst){
    if(::strcmp(pPath_src, pPath_dst)==0){ return false; }

    int fd_src = open(pPath_src, O_RDONLY); if(fd_src<0){ return false; }
    struct stat st; if(fstat(fd_src, &st)!=0){ close(fd_src); return false; }
    int fd_dst = open(pPath_dst, O_CREAT|O_WRONLY, st.st_mode); if(fd_dst<0){ close(fd_src); return false; }

    bool ret = true;
    char pBuf[4096]; // buf[1024];
    ssize_t size;
    struct timespec ts_buf[2];
    while((size=read(fd_src, pBuf, sizeof(pBuf))) > 0){
        if( write(fd_dst, pBuf, size) != size){ ret=false; goto exit; }
    }
    if(ftruncate(fd_dst, st.st_size)!=0){ ret=false; goto exit; } // Align the output file size with the input file when overwriting the existing file larger than input file.

    ts_buf[0]=st.st_atim;
    ts_buf[1]=st.st_mtim;
    if(futimens(fd_dst, ts_buf)!=0){ ret=false; goto exit; }

 exit:
    close(fd_dst);
    close(fd_src);
    return ret;
}
bool sstd::copy(const std::string&  path_src, const char*        pPath_dst){ return sstd::copy( path_src.c_str(), pPath_dst        ); }
bool sstd::copy(const char*        pPath_src, const std::string&  path_dst){ return sstd::copy(pPath_src        ,  path_dst.c_str()); }
bool sstd::copy(const std::string&  path_src, const std::string&  path_dst){ return sstd::copy( path_src.c_str(),  path_dst.c_str()); }

template <typename T>
std::vector<T> rmDuplicate(const std::vector<T>& v){
    using is = std::pair<T,char>;

    std::unordered_map<T,char> hashT;
    for(uint i=0; i<v.size(); ++i){
        hashT.insert( is{v[i], 0} );
    }

    std::vector<T> ret(hashT.size());
    uint i=0;
    for(auto itr=hashT.begin(); itr!=hashT.end(); ++itr){
        ret[i] = itr->first;
        ++i;
    }

    return ret;
}
/*
template <typename T>
std::vector<T> getAND(const std::vector<T>& lhs, const std::vector<T>& rhs){
    using is = std::pair<T,char>;

    std::unordered_map<T,uint64> hashT;
    for(uint i=0; i<lhs.size(); ++i){
        hashT.insert( is{lhs[i], 0} );
    }

    std::vector<T> ret;
    for(uint i=0; i<rhs.size(); ++i){
        if(hashT.find(rhs[i])!=hashT.end()){ continue; }
        ret.push_back( rhs[i] );
    }

    return ret;
}
*/
std::vector<sstd::pathAndType> getAND_ltype(const std::vector<sstd::pathAndType>& lhs, const std::vector<std::string>& rhs){
    using is = std::pair<std::string,uint>;

    std::unordered_map<std::string,uint> hashT;
    for(uint i=0; i<lhs.size(); ++i){
        hashT.insert( is{lhs[i].path, i} );
    }

    std::vector<sstd::pathAndType> ret;
    for(uint i=0; i<rhs.size(); ++i){
        auto itr = hashT.find(rhs[i]);
        if(itr!=hashT.end()){
            ret.push_back( lhs[ itr->second ] );
        }
    }

    return ret;
}
bool sstd::cp  (const char*        pPath_src, const char*        pPath_dst){
    bool TF_file = sstd::isFile(pPath_src);
    bool TF_dir  = sstd::isDir (pPath_src);
//  bool TF_wc   = !(TF_file||TF_dir); // when path include wild card

    if(TF_file){
        // when pPath_src is a file

        sstd::mkdir(sstd::getPath(pPath_dst));
        return sstd::copy(pPath_src, pPath_dst);

    }else if(TF_dir){
        // when pPath_src is a directory

        std::string dstPath_baseDir = std::string(pPath_dst)+'/'+sstd::getDirName(pPath_src);
        struct stat st; if(stat(pPath_src, &st)!=0){ return false; }
        ::mkdir(dstPath_baseDir.c_str(), st.st_mode);

        std::vector<sstd::pathAndType> vPath = sstd::glob_pt(std::string(pPath_src)+"/*", "dfr");
        uint begin_idx = sstd::getDirName_begin_idx(pPath_src);
        for(uint i=0; i!=vPath.size(); ++i){
            if(vPath[i].type=='f'){
                // when vPath[i].path is a file path
                std::string path_dst = std::string(pPath_dst)+'/'+&(vPath[i].path[begin_idx]);
                sstd::copy(vPath[i].path.c_str(), path_dst.c_str());
            }else{
                // when vPath[i].path is a directory path
                std::string dir_dst = std::string(pPath_dst)+'/'+&(vPath[i].path[begin_idx]);
                ::mkdir(dir_dst.c_str(), vPath[i].st.st_mode);
            }
        }

        return true;

    }else{
        // when pPath_src is a path with wild card

        sstd::mkdir(pPath_dst);
        std::vector<sstd::pathAndType> vPath = sstd::glob_pt(sstd::getPath_woWC(pPath_src)+"/*", "dfr");

        std::vector<sstd::pathAndType> vFile, vFile_matchWC;
        std::vector<sstd::pathAndType> vDir;
        for(uint i=0; i<vPath.size(); ++i){
            if(vPath[i].type=='f'){ vFile.push_back( std::move(vPath[i]) );
            }        else         { vDir.push_back( std::move(vPath[i]) ); }
        }

        for(uint i=0; i<vFile.size(); ++i){
            if(sstd::strmatch(vFile[i].path, pPath_src)){
                vFile_matchWC.push_back( std::move(vFile[i]) );
            }
        }

        std::vector<std::string> vDirOfFile;
        for(uint i=0; i<vFile_matchWC.size(); ++i){
            vDirOfFile.push_back( sstd::getPath(vFile_matchWC[i].path.c_str()) );
        }
        vDirOfFile = rmDuplicate<std::string>(vDirOfFile);

        std::vector<std::string> vDirOfFile_splitted;
        for(uint i=0; i<vDirOfFile.size(); ++i){
            std::vector<std::string> vP = sstd::parsePath_withBase(vDirOfFile[i].c_str());
            vDirOfFile_splitted.insert(vDirOfFile_splitted.end(), vP.begin(), vP.end());
        }
        vDirOfFile_splitted = rmDuplicate<std::string>(vDirOfFile_splitted);

        std::sort(vDirOfFile_splitted.begin(), vDirOfFile_splitted.end());
        std::vector<sstd::pathAndType> vDirToMake = getAND_ltype(vDir, vDirOfFile_splitted);

        //---

        uint end_idx = sstd::getDirName_end_idx_woWC(pPath_src);
        for(uint i=0; i<vDirToMake.size(); ++i){
            std::string dir_dst = std::string(pPath_dst)+'/'+&(vDirToMake[i].path[end_idx]);
            ::mkdir(dir_dst.c_str(), vDirToMake[i].st.st_mode);
        }
        for(uint i=0; i<vFile_matchWC.size(); ++i){
            std::string path_dst = std::string(pPath_dst)+'/'+&(vFile_matchWC[i].path[end_idx]);
            sstd::copy(vFile_matchWC[i].path.c_str(), path_dst.c_str());
        }

        return true;
    }

    return true;
}
bool sstd::cp  (const std::string&  path_src, const char*        pPath_dst){ return sstd::cp  ( path_src.c_str(), pPath_dst        ); }
bool sstd::cp  (const char*        pPath_src, const std::string&  path_dst){ return sstd::cp  (pPath_src        ,  path_dst.c_str()); }
bool sstd::cp  (const std::string&  path_src, const std::string&  path_dst){ return sstd::cp  ( path_src.c_str(),  path_dst.c_str()); }
<commit_msg>modify: sstd:cp()<commit_after>#include "cp.hpp"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h> // read(), write()
#include <unordered_map>
#include <algorithm> // sort()

#include "glob.hpp"
#include "mkdir.hpp"
#include "path.hpp"
#include "../string/strmatch.hpp"
#include "../print.hpp" // for dbg

bool sstd::copy(const char*        pPath_src, const char*        pPath_dst){
    if(::strcmp(pPath_src, pPath_dst)==0){ return false; }

    int fd_src = open(pPath_src, O_RDONLY); if(fd_src<0){ return false; }
    struct stat st; if(fstat(fd_src, &st)!=0){ close(fd_src); return false; }
    int fd_dst = open(pPath_dst, O_CREAT|O_WRONLY, st.st_mode); if(fd_dst<0){ close(fd_src); return false; }

    bool ret = true;
    char pBuf[4096]; // buf[1024];
    ssize_t size;
    struct timespec ts_buf[2];
    while((size=read(fd_src, pBuf, sizeof(pBuf))) > 0){
        if( write(fd_dst, pBuf, size) != size){ ret=false; goto exit; }
    }
    if(ftruncate(fd_dst, st.st_size)!=0){ ret=false; goto exit; } // Align the output file size with the input file when overwriting the existing file larger than input file.

    ts_buf[0]=st.st_atim;
    ts_buf[1]=st.st_mtim;
    if(futimens(fd_dst, ts_buf)!=0){ ret=false; goto exit; }

 exit:
    close(fd_dst);
    close(fd_src);
    return ret;
}
bool sstd::copy(const std::string&  path_src, const char*        pPath_dst){ return sstd::copy( path_src.c_str(), pPath_dst        ); }
bool sstd::copy(const char*        pPath_src, const std::string&  path_dst){ return sstd::copy(pPath_src        ,  path_dst.c_str()); }
bool sstd::copy(const std::string&  path_src, const std::string&  path_dst){ return sstd::copy( path_src.c_str(),  path_dst.c_str()); }

template <typename T>
std::vector<T> rmDuplicate(const std::vector<T>& v){
    using is = std::pair<T,char>;

    std::unordered_map<T,char> hashT;
    for(uint i=0; i<v.size(); ++i){
        hashT.insert( is{v[i], 0} );
    }

    std::vector<T> ret(hashT.size());
    uint i=0;
    for(auto itr=hashT.begin(); itr!=hashT.end(); ++itr){
        ret[i] = itr->first;
        ++i;
    }

    return ret;
}
/*
template <typename T>
std::vector<T> getAND(const std::vector<T>& lhs, const std::vector<T>& rhs){
    using is = std::pair<T,char>;

    std::unordered_map<T,uint64> hashT;
    for(uint i=0; i<lhs.size(); ++i){
        hashT.insert( is{lhs[i], 0} );
    }

    std::vector<T> ret;
    for(uint i=0; i<rhs.size(); ++i){
        if(hashT.find(rhs[i])!=hashT.end()){ continue; }
        ret.push_back( rhs[i] );
    }

    return ret;
}
*/
std::vector<sstd::pathAndType> getAND_ltype(const std::vector<sstd::pathAndType>& lhs, const std::vector<std::string>& rhs){
    using is = std::pair<std::string,uint>;

    std::unordered_map<std::string,uint> hashT;
    for(uint i=0; i<lhs.size(); ++i){
        hashT.insert( is{lhs[i].path, i} );
    }

    std::vector<sstd::pathAndType> ret;
    for(uint i=0; i<rhs.size(); ++i){
        auto itr = hashT.find(rhs[i]);
        if(itr!=hashT.end()){
            ret.push_back( lhs[ itr->second ] );
        }
    }

    return ret;
}
bool sstd::cp  (const char*        pPath_src, const char*        pPath_dst){
    bool TF_file = sstd::isFile(pPath_src);
    bool TF_dir  = sstd::isDir (pPath_src);
//  bool TF_wc   = !(TF_file||TF_dir); // when path include wild card

    if(TF_file){
        // when pPath_src is a file

        sstd::mkdir(sstd::getPath(pPath_dst));
        return sstd::copy(pPath_src, pPath_dst);

    }else if(TF_dir){
        // when pPath_src is a directory

        std::string dstPath_baseDir = std::string(pPath_dst)+'/'+sstd::getDirName(pPath_src);
        struct stat st; if(stat(pPath_src, &st)!=0){ return false; }
        ::mkdir(dstPath_baseDir.c_str(), st.st_mode);

        std::vector<sstd::pathAndType> vPath = sstd::glob_pt(std::string(pPath_src)+"/*", "dfr");
        uint begin_idx = sstd::getDirName_begin_idx(pPath_src);
        for(uint i=0; i!=vPath.size(); ++i){
            if(vPath[i].type=='f'){
                // when vPath[i].path is a file path
                std::string path_dst = std::string(pPath_dst)+'/'+&(vPath[i].path[begin_idx]);
                sstd::copy(vPath[i].path.c_str(), path_dst.c_str());
            }else{
                // when vPath[i].path is a directory path
                std::string dir_dst = std::string(pPath_dst)+'/'+&(vPath[i].path[begin_idx]);
                ::mkdir(dir_dst.c_str(), vPath[i].st.st_mode);
            }
        }

        return true;

    }else{
        // when pPath_src is a path with wild card

        sstd::mkdir(pPath_dst);
        std::vector<sstd::pathAndType> vPath = sstd::glob_pt(sstd::getPath_woWC(pPath_src)+"/*", "dfr");

        std::vector<sstd::pathAndType> vFile, vFile_matchWC;
        std::vector<sstd::pathAndType> vDir;
        for(uint i=0; i<vPath.size(); ++i){
            if(vPath[i].type=='f'){ vFile.push_back( std::move(vPath[i]) );
            }        else         { vDir.push_back( std::move(vPath[i]) ); }
        }

        for(uint i=0; i<vFile.size(); ++i){
            if(!sstd::strmatch(vFile[i].path, pPath_src)){ continue; }
            vFile_matchWC.push_back( std::move(vFile[i]) );
        }

        std::vector<std::string> vDirOfFile;
        for(uint i=0; i<vFile_matchWC.size(); ++i){
            vDirOfFile.push_back( sstd::getPath(vFile_matchWC[i].path.c_str()) );
        }
        vDirOfFile = rmDuplicate<std::string>(vDirOfFile);

        std::vector<std::string> vDirOfFile_splitted;
        for(uint i=0; i<vDirOfFile.size(); ++i){
            std::vector<std::string> vP = sstd::parsePath_withBase(vDirOfFile[i].c_str());
            vDirOfFile_splitted.insert(vDirOfFile_splitted.end(), vP.begin(), vP.end());
        }
        vDirOfFile_splitted = rmDuplicate<std::string>(vDirOfFile_splitted);

        std::sort(vDirOfFile_splitted.begin(), vDirOfFile_splitted.end());
        std::vector<sstd::pathAndType> vDirToMake = getAND_ltype(vDir, vDirOfFile_splitted);

        //---

        uint end_idx = sstd::getDirName_end_idx_woWC(pPath_src);
        for(uint i=0; i<vDirToMake.size(); ++i){
            std::string dir_dst = std::string(pPath_dst)+'/'+&(vDirToMake[i].path[end_idx]);
            ::mkdir(dir_dst.c_str(), vDirToMake[i].st.st_mode);
        }
        for(uint i=0; i<vFile_matchWC.size(); ++i){
            std::string path_dst = std::string(pPath_dst)+'/'+&(vFile_matchWC[i].path[end_idx]);
            sstd::copy(vFile_matchWC[i].path.c_str(), path_dst.c_str());
        }

        return true;
    }

    return true;
}
bool sstd::cp  (const std::string&  path_src, const char*        pPath_dst){ return sstd::cp  ( path_src.c_str(), pPath_dst        ); }
bool sstd::cp  (const char*        pPath_src, const std::string&  path_dst){ return sstd::cp  (pPath_src        ,  path_dst.c_str()); }
bool sstd::cp  (const std::string&  path_src, const std::string&  path_dst){ return sstd::cp  ( path_src.c_str(),  path_dst.c_str()); }
<|endoftext|>


<commit_before>/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-4-28 22:56:15
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init() {
  inv[1] = 1;
  for (int i=2; i<MAX_SIZE; i++) {
    inv[i] = ((MOD - inv[MOD%i]) * (MOD/i))%MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i=1; i<MAX_SIZE; i++) {
    fact[i] = (i * fact[i-1])%MOD;
    factinv[i] = (inv[i] * factinv[i-1])%MOD;
  }
}

long long C(int n, int k) {
  if (n >=0 && k >= 0 && n-k >= 0) {
    return ((fact[n] * factinv[k])%MOD * factinv[n-k])%MOD;
  }
  return 0;
}

long long power(long long x, long long n) {
  if (n == 0) {
    return 1;
  } else if (n%2 == 1) {
    return (x * power(x, n-1)) % MOD;
  } else {
    long long half = power(x, n/2);
    return (half * half) % MOD;
  }
}

long long gcm(long long a, long long b) {
  if (a < b) {
    return gcm(b, a);
  }
  if (b == 0) return a;
  return gcm(b, a%b);
}

ll N;
ll Ika[200010];

int main()
{
  init();
  cin >> N;
  Ika[0] = Ika[1] = 0;
  if (N == 2)
  {
    cout << 1 << endl;
    return 0;
  }
  for (auto A = 2; A <= N - 1; A++)
  {
    ll x = N - 1 - A;
    if (x >= 0 && A >= 0)
    {
      Ika[A] = (((C(A - 1, N - 1 - A) * fact[x]) % MOD) * fact[A]) % MOD;
      if (N < 100)
      {
        cerr << "Ika[" << A << "] = " << Ika[A] << endl;
      }
    }
  }
  ll ans = 0;
  for (ll A = 1; A <= N - 1; A++)
  {
    ans += (A * ((Ika[A] + MOD - Ika[A - 1]) % MOD)) % MOD;
    ans %= MOD;
  }
  cout << ans << endl;
}<commit_msg>tried C.cpp to 'C'<commit_after>/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-4-28 22:56:15
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init() {
  inv[1] = 1;
  for (int i=2; i<MAX_SIZE; i++) {
    inv[i] = ((MOD - inv[MOD%i]) * (MOD/i))%MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i=1; i<MAX_SIZE; i++) {
    fact[i] = (i * fact[i-1])%MOD;
    factinv[i] = (inv[i] * factinv[i-1])%MOD;
  }
}

long long C(int n, int k) {
  if (n >=0 && k >= 0 && n-k >= 0) {
    return ((fact[n] * factinv[k])%MOD * factinv[n-k])%MOD;
  }
  return 0;
}

long long power(long long x, long long n) {
  if (n == 0) {
    return 1;
  } else if (n%2 == 1) {
    return (x * power(x, n-1)) % MOD;
  } else {
    long long half = power(x, n/2);
    return (half * half) % MOD;
  }
}

long long gcm(long long a, long long b) {
  if (a < b) {
    return gcm(b, a);
  }
  if (b == 0) return a;
  return gcm(b, a%b);
}

ll N;
ll Ika[200010];

int main()
{
  init();
  cin >> N;
  Ika[0] = Ika[1] = 0;
  if (N == 2)
  {
    cout << 1 << endl;
    return 0;
  }
  for (ll A = 2; A <= N - 1; A++)
  {
    ll x = N - 1 - A;
    if (x >= 0 && A >= 0)
    {
      Ika[A] = (((C(A - 1, N - 1 - A) * fact[x]) % MOD) * fact[A]) % MOD;
      cerr << "Ika[" << A << "] = " << Ika[A] << endl;
    }
  }
  ll ans = 0;
  for (ll A = 1; A <= N - 1; A++)
  {
    ans += (A * ((Ika[A] + MOD - Ika[A - 1]) % MOD)) % MOD;
    ans %= MOD;
  }
  // cout << ans << endl;
}<|endoftext|>


<commit_before>/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-5-20 21:05:39
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
int P[200010];

int solve()
{
  int now = 0;
  for (auto i = 0; i < N; i++)
  {
    if (P[i] == now + 1)
    {
      now++;
    }
  }
  return N - now;
}

int main()
{
  cin >> N;
  for (auto i = 0; i < N; i++)
  {
    cin >> P[i];
  }
  int ans = solve();
  reverse(P, P + 200010);
  for (auto i = 0; i < N; i++)
  {
    P[i] = N - P[i] + 1;
  }
  ans = min(ans, solve());
  cout << ans << endl;
}<commit_msg>tried B.cpp to 'B'<commit_after>/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-5-20 21:05:39
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
int P[200010];

int solve()
{
  int now = 0;
  for (auto i = 0; i < N; i++)
  {
    if (P[i] == now + 1)
    {
      now++;
    }
  }
  return N - now;
}

int main()
{
  cin >> N;
  for (auto i = 0; i < N; i++)
  {
    cin >> P[i];
  }
  int ans = solve();
  reverse(P, P + 200010);
  for (auto i = 0; i < N; i++)
  {
    P[i] = N - P[i] + 1;
    cerr << "P[" << i << "] = " << P[i] << endl;
  }
  ans = min(ans, solve());
  cout << ans << endl;
}<|endoftext|>


<commit_before>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-12-1 22:41:10
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, C;
int s[100010];
int t[100010];
int c[100010];
bool broad[30][100010];
typedef tuple<int, int> X;
vector<X> V;
int ans = 0;

int main()
{
  cin >> N >> C;
  for (auto i = 0; i < N; i++)
  {
    cin >> s[i] >> t[i] >> c[i];
  }
  fill(&broad[0][0], &broad[0][0] + 30 * 100010, false);
  for (auto i = 0; i < N; i++)
  {
    for (auto j = s[i] - 1; j < t[i]; j++)
    {
      broad[c[i]][j] = true;
    }
  }
  for (auto i = 0; i < C; i++)
  {
    if (broad[i][0])
    {
      V.push_back(X(0, 1));
    }
    for (auto j = 1; j < 100010; j++)
    {
      if (broad[i][j - 1] && !broad[i][j])
      {
        V.push_back(X(j, 0));
      }
      else if (!broad[i][j - 1] && broad[i][j])
      {
        V.push_back(X(j, 1));
      }
    }
  }
  sort(V.begin(), V.end());
  int t = 0;
  for (auto x : V)
  {
    cerr << "(" << get<0>(x) << ", " << get<1>(x) << ")" << endl;
    if (get<1>(x) == 0)
    {
      t--;
    }
    else
    {
      t++;
    }
    ans = max(ans, t);
  }
  cout << ans << endl;
}<commit_msg>submit D.cpp to 'D - Recording' (abc080) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-12-1 22:41:10
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, C;
int s[100010];
int t[100010];
int c[100010];
bool broad[30][100010];
typedef tuple<int, int> X;
vector<X> V;
int ans = 0;

int main()
{
  cin >> N >> C;
  for (auto i = 0; i < N; i++)
  {
    cin >> s[i] >> t[i] >> c[i];
    c[i]--;
  }
  fill(&broad[0][0], &broad[0][0] + 30 * 100010, false);
  for (auto i = 0; i < N; i++)
  {
    for (auto j = s[i] - 1; j < t[i]; j++)
    {
      broad[c[i]][j] = true;
    }
  }
  for (auto i = 0; i < C; i++)
  {
    if (broad[i][0])
    {
      V.push_back(X(0, 1));
    }
    for (auto j = 1; j < 100010; j++)
    {
      if (broad[i][j - 1] && !broad[i][j])
      {
        V.push_back(X(j, 0));
      }
      else if (!broad[i][j - 1] && broad[i][j])
      {
        V.push_back(X(j, 1));
      }
    }
  }
  sort(V.begin(), V.end());
  int t = 0;
  for (auto x : V)
  {
    // cerr << "(" << get<0>(x) << ", " << get<1>(x) << ")" << endl;
    if (get<1>(x) == 0)
    {
      t--;
    }
    else
    {
      t++;
    }
    ans = max(ans, t);
  }
  cout << ans << endl;
}<|endoftext|>


<commit_before>//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the helper classes used to build and interpret debug
// information in LLVM IR form.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DebugInfo.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::dwarf;

DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {
  if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope))
    return LocalScope->getSubprogram();
  return nullptr;
}

//===----------------------------------------------------------------------===//
// DebugInfoFinder implementations.
//===----------------------------------------------------------------------===//

void DebugInfoFinder::reset() {
  CUs.clear();
  SPs.clear();
  GVs.clear();
  TYs.clear();
  Scopes.clear();
  NodesSeen.clear();
}

void DebugInfoFinder::processModule(const Module &M) {
  for (auto *CU : M.debug_compile_units()) {
    addCompileUnit(CU);
    for (auto *DIG : CU->getGlobalVariables()) {
      if (addGlobalVariable(DIG)) {
        processScope(DIG->getScope());
        processType(DIG->getType().resolve());
      }
    }
    for (auto *ET : CU->getEnumTypes())
      processType(ET);
    for (auto *RT : CU->getRetainedTypes())
      if (auto *T = dyn_cast<DIType>(RT))
        processType(T);
      else
        processSubprogram(cast<DISubprogram>(RT));
    for (auto *Import : CU->getImportedEntities()) {
      auto *Entity = Import->getEntity().resolve();
      if (auto *T = dyn_cast<DIType>(Entity))
        processType(T);
      else if (auto *SP = dyn_cast<DISubprogram>(Entity))
        processSubprogram(SP);
      else if (auto *NS = dyn_cast<DINamespace>(Entity))
        processScope(NS->getScope());
      else if (auto *M = dyn_cast<DIModule>(Entity))
        processScope(M->getScope());
    }
  }
  for (auto &F : M.functions())
    if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
      processSubprogram(SP);
}

void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
  if (!Loc)
    return;
  processScope(Loc->getScope());
  processLocation(M, Loc->getInlinedAt());
}

void DebugInfoFinder::processType(DIType *DT) {
  if (!addType(DT))
    return;
  processScope(DT->getScope().resolve());
  if (auto *ST = dyn_cast<DISubroutineType>(DT)) {
    for (DITypeRef Ref : ST->getTypeArray())
      processType(Ref.resolve());
    return;
  }
  if (auto *DCT = dyn_cast<DICompositeType>(DT)) {
    processType(DCT->getBaseType().resolve());
    for (Metadata *D : DCT->getElements()) {
      if (auto *T = dyn_cast<DIType>(D))
        processType(T);
      else if (auto *SP = dyn_cast<DISubprogram>(D))
        processSubprogram(SP);
    }
    return;
  }
  if (auto *DDT = dyn_cast<DIDerivedType>(DT)) {
    processType(DDT->getBaseType().resolve());
  }
}

void DebugInfoFinder::processScope(DIScope *Scope) {
  if (!Scope)
    return;
  if (auto *Ty = dyn_cast<DIType>(Scope)) {
    processType(Ty);
    return;
  }
  if (auto *CU = dyn_cast<DICompileUnit>(Scope)) {
    addCompileUnit(CU);
    return;
  }
  if (auto *SP = dyn_cast<DISubprogram>(Scope)) {
    processSubprogram(SP);
    return;
  }
  if (!addScope(Scope))
    return;
  if (auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) {
    processScope(LB->getScope());
  } else if (auto *NS = dyn_cast<DINamespace>(Scope)) {
    processScope(NS->getScope());
  } else if (auto *M = dyn_cast<DIModule>(Scope)) {
    processScope(M->getScope());
  }
}

void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
  if (!addSubprogram(SP))
    return;
  processScope(SP->getScope().resolve());
  processType(SP->getType());
  for (auto *Element : SP->getTemplateParams()) {
    if (auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) {
      processType(TType->getType().resolve());
    } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) {
      processType(TVal->getType().resolve());
    }
  }
}

void DebugInfoFinder::processDeclare(const Module &M,
                                     const DbgDeclareInst *DDI) {
  auto *N = dyn_cast<MDNode>(DDI->getVariable());
  if (!N)
    return;

  auto *DV = dyn_cast<DILocalVariable>(N);
  if (!DV)
    return;

  if (!NodesSeen.insert(DV).second)
    return;
  processScope(DV->getScope());
  processType(DV->getType().resolve());
}

void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
  auto *N = dyn_cast<MDNode>(DVI->getVariable());
  if (!N)
    return;

  auto *DV = dyn_cast<DILocalVariable>(N);
  if (!DV)
    return;

  if (!NodesSeen.insert(DV).second)
    return;
  processScope(DV->getScope());
  processType(DV->getType().resolve());
}

bool DebugInfoFinder::addType(DIType *DT) {
  if (!DT)
    return false;

  if (!NodesSeen.insert(DT).second)
    return false;

  TYs.push_back(const_cast<DIType *>(DT));
  return true;
}

bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) {
  if (!CU)
    return false;
  if (!NodesSeen.insert(CU).second)
    return false;

  CUs.push_back(CU);
  return true;
}

bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable *DIG) {
  if (!DIG)
    return false;

  if (!NodesSeen.insert(DIG).second)
    return false;

  GVs.push_back(DIG);
  return true;
}

bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {
  if (!SP)
    return false;

  if (!NodesSeen.insert(SP).second)
    return false;

  SPs.push_back(SP);
  return true;
}

bool DebugInfoFinder::addScope(DIScope *Scope) {
  if (!Scope)
    return false;
  // FIXME: Ocaml binding generates a scope with no content, we treat it
  // as null for now.
  if (Scope->getNumOperands() == 0)
    return false;
  if (!NodesSeen.insert(Scope).second)
    return false;
  Scopes.push_back(Scope);
  return true;
}

bool llvm::stripDebugInfo(Function &F) {
  bool Changed = false;
  if (F.getSubprogram()) {
    Changed = true;
    F.setSubprogram(nullptr);
  }

  Function *Declare = F.getParent()->getFunction("llvm.dbg.declare");
  Function *DbgVal = F.getParent()->getFunction("llvm.dbg.value");
  for (BasicBlock &BB : F) {
    for (auto II = BB.begin(), End = BB.end(); II != End;) {
      Instruction &I = *II++; // We may delete the instruction, increment now.
      // Remove all of the calls to the debugger intrinsics, and remove them
      // from the module.
      CallInst *CI = dyn_cast<CallInst>(&I);
      if (CI && CI->getCalledFunction() &&
          (CI->getCalledFunction() == Declare ||
           CI->getCalledFunction() == DbgVal)) {
        CI->eraseFromParent();
        Changed = true;
      }
      if (I.getDebugLoc()) {
        Changed = true;
        I.setDebugLoc(DebugLoc());
      }
    }
  }
  return Changed;
}

bool llvm::StripDebugInfo(Module &M) {
  bool Changed = false;

  for (Module::named_metadata_iterator NMI = M.named_metadata_begin(),
         NME = M.named_metadata_end(); NMI != NME;) {
    NamedMDNode *NMD = &*NMI;
    ++NMI;
    if (NMD->getName().startswith("llvm.dbg.")) {
      NMD->eraseFromParent();
      Changed = true;
    }
  }

  for (Function &F : M)
    Changed |= stripDebugInfo(F);

  if (GVMaterializer *Materializer = M.getMaterializer())
    Materializer->setStripDebugInfo();

  return Changed;
}

unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
  if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
          M.getModuleFlag("Debug Info Version")))
    return Val->getZExtValue();
  return 0;
}
<commit_msg>Fix stripDebugInfo: was modifying "DebugLoc" attached to the intrinsic after deleting it.<commit_after>//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the helper classes used to build and interpret debug
// information in LLVM IR form.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DebugInfo.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::dwarf;

DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {
  if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope))
    return LocalScope->getSubprogram();
  return nullptr;
}

//===----------------------------------------------------------------------===//
// DebugInfoFinder implementations.
//===----------------------------------------------------------------------===//

void DebugInfoFinder::reset() {
  CUs.clear();
  SPs.clear();
  GVs.clear();
  TYs.clear();
  Scopes.clear();
  NodesSeen.clear();
}

void DebugInfoFinder::processModule(const Module &M) {
  for (auto *CU : M.debug_compile_units()) {
    addCompileUnit(CU);
    for (auto *DIG : CU->getGlobalVariables()) {
      if (addGlobalVariable(DIG)) {
        processScope(DIG->getScope());
        processType(DIG->getType().resolve());
      }
    }
    for (auto *ET : CU->getEnumTypes())
      processType(ET);
    for (auto *RT : CU->getRetainedTypes())
      if (auto *T = dyn_cast<DIType>(RT))
        processType(T);
      else
        processSubprogram(cast<DISubprogram>(RT));
    for (auto *Import : CU->getImportedEntities()) {
      auto *Entity = Import->getEntity().resolve();
      if (auto *T = dyn_cast<DIType>(Entity))
        processType(T);
      else if (auto *SP = dyn_cast<DISubprogram>(Entity))
        processSubprogram(SP);
      else if (auto *NS = dyn_cast<DINamespace>(Entity))
        processScope(NS->getScope());
      else if (auto *M = dyn_cast<DIModule>(Entity))
        processScope(M->getScope());
    }
  }
  for (auto &F : M.functions())
    if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
      processSubprogram(SP);
}

void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
  if (!Loc)
    return;
  processScope(Loc->getScope());
  processLocation(M, Loc->getInlinedAt());
}

void DebugInfoFinder::processType(DIType *DT) {
  if (!addType(DT))
    return;
  processScope(DT->getScope().resolve());
  if (auto *ST = dyn_cast<DISubroutineType>(DT)) {
    for (DITypeRef Ref : ST->getTypeArray())
      processType(Ref.resolve());
    return;
  }
  if (auto *DCT = dyn_cast<DICompositeType>(DT)) {
    processType(DCT->getBaseType().resolve());
    for (Metadata *D : DCT->getElements()) {
      if (auto *T = dyn_cast<DIType>(D))
        processType(T);
      else if (auto *SP = dyn_cast<DISubprogram>(D))
        processSubprogram(SP);
    }
    return;
  }
  if (auto *DDT = dyn_cast<DIDerivedType>(DT)) {
    processType(DDT->getBaseType().resolve());
  }
}

void DebugInfoFinder::processScope(DIScope *Scope) {
  if (!Scope)
    return;
  if (auto *Ty = dyn_cast<DIType>(Scope)) {
    processType(Ty);
    return;
  }
  if (auto *CU = dyn_cast<DICompileUnit>(Scope)) {
    addCompileUnit(CU);
    return;
  }
  if (auto *SP = dyn_cast<DISubprogram>(Scope)) {
    processSubprogram(SP);
    return;
  }
  if (!addScope(Scope))
    return;
  if (auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) {
    processScope(LB->getScope());
  } else if (auto *NS = dyn_cast<DINamespace>(Scope)) {
    processScope(NS->getScope());
  } else if (auto *M = dyn_cast<DIModule>(Scope)) {
    processScope(M->getScope());
  }
}

void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
  if (!addSubprogram(SP))
    return;
  processScope(SP->getScope().resolve());
  processType(SP->getType());
  for (auto *Element : SP->getTemplateParams()) {
    if (auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) {
      processType(TType->getType().resolve());
    } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) {
      processType(TVal->getType().resolve());
    }
  }
}

void DebugInfoFinder::processDeclare(const Module &M,
                                     const DbgDeclareInst *DDI) {
  auto *N = dyn_cast<MDNode>(DDI->getVariable());
  if (!N)
    return;

  auto *DV = dyn_cast<DILocalVariable>(N);
  if (!DV)
    return;

  if (!NodesSeen.insert(DV).second)
    return;
  processScope(DV->getScope());
  processType(DV->getType().resolve());
}

void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
  auto *N = dyn_cast<MDNode>(DVI->getVariable());
  if (!N)
    return;

  auto *DV = dyn_cast<DILocalVariable>(N);
  if (!DV)
    return;

  if (!NodesSeen.insert(DV).second)
    return;
  processScope(DV->getScope());
  processType(DV->getType().resolve());
}

bool DebugInfoFinder::addType(DIType *DT) {
  if (!DT)
    return false;

  if (!NodesSeen.insert(DT).second)
    return false;

  TYs.push_back(const_cast<DIType *>(DT));
  return true;
}

bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) {
  if (!CU)
    return false;
  if (!NodesSeen.insert(CU).second)
    return false;

  CUs.push_back(CU);
  return true;
}

bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable *DIG) {
  if (!DIG)
    return false;

  if (!NodesSeen.insert(DIG).second)
    return false;

  GVs.push_back(DIG);
  return true;
}

bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {
  if (!SP)
    return false;

  if (!NodesSeen.insert(SP).second)
    return false;

  SPs.push_back(SP);
  return true;
}

bool DebugInfoFinder::addScope(DIScope *Scope) {
  if (!Scope)
    return false;
  // FIXME: Ocaml binding generates a scope with no content, we treat it
  // as null for now.
  if (Scope->getNumOperands() == 0)
    return false;
  if (!NodesSeen.insert(Scope).second)
    return false;
  Scopes.push_back(Scope);
  return true;
}

bool llvm::stripDebugInfo(Function &F) {
  bool Changed = false;
  if (F.getSubprogram()) {
    Changed = true;
    F.setSubprogram(nullptr);
  }

  Function *Declare = F.getParent()->getFunction("llvm.dbg.declare");
  Function *DbgVal = F.getParent()->getFunction("llvm.dbg.value");
  for (BasicBlock &BB : F) {
    for (auto II = BB.begin(), End = BB.end(); II != End;) {
      Instruction &I = *II++; // We may delete the instruction, increment now.
      // Remove all of the calls to the debugger intrinsics, and remove them
      // from the module.
      CallInst *CI = dyn_cast<CallInst>(&I);
      if (CI && CI->getCalledFunction() &&
          (CI->getCalledFunction() == Declare ||
           CI->getCalledFunction() == DbgVal)) {
        CI->eraseFromParent();
        Changed = true;
        continue;
      }
      if (I.getDebugLoc()) {
        Changed = true;
        I.setDebugLoc(DebugLoc());
      }
    }
  }
  return Changed;
}

bool llvm::StripDebugInfo(Module &M) {
  bool Changed = false;

  for (Module::named_metadata_iterator NMI = M.named_metadata_begin(),
         NME = M.named_metadata_end(); NMI != NME;) {
    NamedMDNode *NMD = &*NMI;
    ++NMI;
    if (NMD->getName().startswith("llvm.dbg.")) {
      NMD->eraseFromParent();
      Changed = true;
    }
  }

  for (Function &F : M)
    Changed |= stripDebugInfo(F);

  if (GVMaterializer *Materializer = M.getMaterializer())
    Materializer->setStripDebugInfo();

  return Changed;
}

unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
  if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
          M.getModuleFlag("Debug Info Version")))
    return Val->getZExtValue();
  return 0;
}
<|endoftext|>


<commit_before>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 12/9/2018, 10:40:14 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 100000000000000;

ll f(ll b, ll n)
{
  if (n < b)
  {
    return n;
  }
  return f(b, n / b) + n % b;
}

ll N, S;

int main()
{
  cin >> N >> S;
  if (N < S)
  {
    cout << -1 << endl;
    return 0;
  }
  if (N == S)
  {
    cout << N + 1 << endl;
    return 0;
  }
  for (ll b = 2; b * b <= N; b++)
  {
    if (f(b, N) == S)
    {
      cout << b << endl;
      return 0;
    }
  }
  ll ans = infty;
  for (ll p = 1; p * p <= N; p++)
  {
    ll q = S - p;
    if ((N - q) % p != 0)
    {
      continue;
    }
    ll b = (N - q) / p;
    if (!(0 <= q && q < b && p < b))
    {
      continue;
    }
    if (f(b, N) == S)
    {
      ans = min(ans, b);
    }
  }
  if (ans < infty)
  {
    cout << ans << endl;
  }
  else
  {
    cout << -1 << endl;
  }
}<commit_msg>submit D.cpp to 'D - 桁和 / Digit Sum' (abc044) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 12/9/2018, 10:40:14 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 100000000000000;

ll f(ll b, ll n)
{
  if (n < b)
  {
    return n;
  }
  return f(b, n / b) + n % b;
}

ll N, S;

int main()
{
  cin >> N >> S;
  if (N < S)
  {
    cout << -1 << endl;
    return 0;
  }
  if (N == S)
  {
    cout << N + 1 << endl;
    return 0;
  }
  for (auto b = 2; b * b <= N; b++)
  {
    if (f(b, N) == S)
    {
      cout << b << endl;
      return 0;
    }
  }
  ll ans = infty;
  for (auto p = 1; p * p <= N; p++)
  {
    ll q = S - p;
    if ((N - q) % p != 0)
    {
      continue;
    }
    ll b = (N - q) / p;
    if (!(0 <= q && q < b && p < b))
    {
      continue;
    }
    if (f(b, N) == S)
    {
      ans = min(ans, b);
    }
  }
  if (ans < infty)
  {
    cout << ans << endl;
  }
  else
  {
    cout << -1 << endl;
  }
}<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 3/23/2019, 10:52:02 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 100000000000000007;

ll N, A, B;
int p[5010];
ll R[5010][5010];
ll L[5010][5010];
ll cost[5010][5010];

ll calc(int l, int r)
{
  if (cost[l][r] < infty)
  {
    return cost[l][r];
  }
  else if (l == r)
  {
    cost[l][r] = 0;
  }
  else if (l == r + 1)
  {
    cost[l][r] = 0;
  }
  else if (l == r + 2)
  {
#if DEBUG == 1
    cerr << "(" << l << ", " << r << ")" << endl;
#endif
    if (p[l] < p[l + 1])
    {
      cost[l][r] = 0;
    }
    else
    {
      cost[l][r] = min(A, B);
    }
  }
  else
  {
    cost[l][r] = min(A, B * L[l][r - 1]) + calc(l + 1, r);
    cost[l][r] = min(cost[l][r], min(B, A * R[r - 1][l])) + calc(l, r - 1);
  }
#if DEBUG == 1
  cerr << "cost[" << l << "][" << r << "] = " << cost[l][r] << endl;
#endif
  return cost[l][r];
}

int main()
{
  cin >> N >> A >> B;
  for (auto i = 0; i < N; i++)
  {
    cin >> p[i];
    p[i]--;
  }
  fill(&R[0][0], &R[0][0] + 5010 * 5010, N + 1);
  fill(&L[0][0], &L[0][0] + 5010 * 5010, N + 1);
  fill(&cost[0][0], &cost[0][0] + 5010 * 5010, infty);
  for (auto i = 0; i < N; i++)
  {
    R[i][i] = 0;
    for (auto j = i + 1; j < N; j++)
    {
      R[i][j] = R[i][j - 1];
      if (p[i] > p[j])
      {
        R[i][j]++;
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    L[i][i] = 0;
    for (auto j = i - 1; j >= 0; j--)
    {
      L[i][j] = L[i][j + 1];
      if (p[i] < p[j])
      {
        L[i][j]++;
      }
    }
  }
  cout << calc(0, N) << endl;
}<commit_msg>tried D.cpp to 'D'<commit_after>#define DEBUG 1

/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 3/23/2019, 10:52:02 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 100000000000000007;

ll N, A, B;
int p[5010];
ll R[5010][5010];
ll L[5010][5010];
ll cost[5010][5010];

ll calc(int l, int r)
{
  if (cost[l][r] < infty)
  {
    return cost[l][r];
  }
  else if (l == r)
  {
    cost[l][r] = 0;
  }
  else if (l + 1 == r)
  {
    cost[l][r] = 0;
  }
  else if (l + 2 == r)
  {
#if DEBUG == 1
    cerr << "(" << l << ", " << r << ")" << endl;
#endif
    if (p[l] < p[l + 1])
    {
      cost[l][r] = 0;
    }
    else
    {
      cost[l][r] = min(A, B);
    }
  }
  else
  {
    cost[l][r] = min(A, B * L[l][r - 1]) + calc(l + 1, r);
    cost[l][r] = min(cost[l][r], min(B, A * R[r - 1][l])) + calc(l, r - 1);
  }
#if DEBUG == 1
  cerr << "cost[" << l << "][" << r << "] = " << cost[l][r] << endl;
#endif
  return cost[l][r];
}

int main()
{
  cin >> N >> A >> B;
  for (auto i = 0; i < N; i++)
  {
    cin >> p[i];
    p[i]--;
  }
  fill(&R[0][0], &R[0][0] + 5010 * 5010, N + 1);
  fill(&L[0][0], &L[0][0] + 5010 * 5010, N + 1);
  fill(&cost[0][0], &cost[0][0] + 5010 * 5010, infty);
  for (auto i = 0; i < N; i++)
  {
    R[i][i] = 0;
    for (auto j = i + 1; j < N; j++)
    {
      R[i][j] = R[i][j - 1];
      if (p[i] > p[j])
      {
        R[i][j]++;
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    L[i][i] = 0;
    for (auto j = i - 1; j >= 0; j--)
    {
      L[i][j] = L[i][j + 1];
      if (p[i] < p[j])
      {
        L[i][j]++;
      }
    }
  }
  cout << calc(0, N) << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 10/18/2019, 7:51:02 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll N, L;
constexpr double pi{M_PI};

double X(double t)
{
  return cos(2 * pi * t / L);
}

double Y(double t)
{
  return sin(2 * pi * t / L);
}

int main()
{
  cin >> N >> L;
  vector<double> T(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> T[i];
  }
  double sum_X{0.0}, sum_Y{0.0};
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      double h{(T[i] + T[j]) / 2};
      ll cnt{N - (j - i - 1) - 2};
      sum_X += X(h) * cnt;
      sum_Y += Y(h) * cnt;
      ll cnt_2{N - 2 - cnt};
      sum_X += X(h + pi) * cnt_2;
      sum_Y += Y(h + pi) * cnt_2;
    }
  }
  ll C{N * (N - 1) * (N - 2) / 6};
  cout << fixed << setprecision(15) << sum_X / C << " " << sum_Y / C << endl;
}<commit_msg>tried D.cpp to 'D'<commit_after>#define DEBUG 1
/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 10/18/2019, 7:51:02 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll N, L;
constexpr double pi{M_PI};

double X(double t)
{
  return cos(2 * pi * t / L);
}

double Y(double t)
{
  return sin(2 * pi * t / L);
}

int main()
{
  cin >> N >> L;
  vector<double> T(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> T[i];
  }
  double sum_X{0.0}, sum_Y{0.0};
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      double h{(T[i] + T[j]) / 2};
      ll cnt{N - (j - i - 1) - 2};
#if DEBUG == 1
      cerr << "cnt = " << cnt << ", h = " << h << endl;
#endif
      sum_X += X(h) * cnt;
      sum_Y += Y(h) * cnt;
      ll cnt_2{N - 2 - cnt};
      sum_X += X(h + pi) * cnt_2;
      sum_Y += Y(h + pi) * cnt_2;
    }
  }
  ll C{N * (N - 1) * (N - 2) / 6};
  cout << fixed << setprecision(15) << sum_X / C << " " << sum_Y / C << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2019/11/5 22:01:12
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 998244353;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 20000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

combination C;

mint catalan(ll x, ll y)
{
  return C(x + y, y) - C(x + y, y - 1);
}

int main()
{
  ll N, A, B;
  cin >> N >> A >> B;
  ll M{min({A, N - B, B - 1})};
  mint ans{0};
  for (auto i = 0; i < M; i++)
  {
    mint tmp{catalan(B - 1, i)};
    if (i + B == N && A == i)
    {
      ans += tmp;
    }
    else
    {
      ll x{N - B - i - 1};
      ll y{A - i + 1};
      ans += tmp * C(x + y - 1, x);
    }
  }
  cout << ans << endl;
}<commit_msg>tried F.cpp to 'F'<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2019/11/5 22:01:12
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 998244353;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 20000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

combination C;

mint catalan(ll x, ll y)
{
  return C(x + y, y) - C(x + y, y - 1);
}

int main()
{
  ll N, A, B;
  cin >> N >> A >> B;
  ll M{min({A, N - B, B - 1})};
  mint ans{0};
  for (auto i = 0; i <= M; i++)
  {
    mint tmp{catalan(B - 1, i)};
    if (i + B == N && A == i)
    {
      ans += tmp;
    }
    else
    {
      ll x{N - B - i - 1};
      ll y{A - i + 1};
      ans += tmp * C(x + y - 1, x);
    }
  }
  cout << ans << endl;
}<|endoftext|>