<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 *
 * 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 "DeviceKey.h"

#if DEVICEKEY_ENABLED
#include "mbedtls/config.h"
#include "mbedtls/cmac.h"
#include "KVStore.h"
#include "TDBStore.h"
#include "KVMap.h"
#include "kv_config.h"
#include "mbed_wait_api.h"
#include "stdlib.h"
#include "platform/mbed_error.h"
#include <string.h>
#include "entropy.h"
#include "platform_mbed.h"
#include "mbed_trace.h"
#include "ssl_internal.h"

#define TRACE_GROUP "DEVKEY"

#if !defined(MBEDTLS_CMAC_C)
#error [NOT_SUPPORTED] MBEDTLS_CMAC_C needs to be enabled for this driver
#else

namespace mbed {

#define DEVKEY_WRITE_UINT32_LE( dst, src )                              \
    do                                                                  \
    {                                                                   \
        (dst)[0] = ( (src) >> 0 ) & 0xFF;                               \
        (dst)[1] = ( (src) >> 8 ) & 0xFF;                               \
        (dst)[2] = ( (src) >> 16 ) & 0xFF;                              \
        (dst)[3] = ( (src) >> 24 ) & 0xFF;                              \
    } while( 0 )

#define DEVKEY_WRITE_UINT8_LE( dst, src )                               \
    do                                                                  \
    {                                                                   \
        (dst)[0] = (src) & 0xFF;                                        \
    } while( 0 )

DeviceKey::DeviceKey()
{
    int ret = kv_init_storage_config();
    if (ret != MBED_SUCCESS) {
        tr_error("DeviceKey: Fail to initialize KvStore configuration.");
    }
    return;
}

DeviceKey::~DeviceKey()
{
    return;
}

int DeviceKey::generate_derived_key(const unsigned char *salt, size_t isalt_size, unsigned char *output,
                                    uint16_t ikey_type)
{
    uint32_t key_buff[DEVICE_KEY_32BYTE / sizeof(uint32_t)];
    size_t actual_size = DEVICE_KEY_32BYTE;

    if (DEVICE_KEY_16BYTE != ikey_type && DEVICE_KEY_32BYTE != ikey_type) {
        return DEVICEKEY_INVALID_KEY_TYPE;
    }

    actual_size = DEVICE_KEY_16BYTE != ikey_type ? DEVICE_KEY_32BYTE : DEVICE_KEY_16BYTE;

    //First try to read the key from KVStore
    int ret = read_key_from_kvstore(key_buff, actual_size);
    if (DEVICEKEY_SUCCESS != ret && DEVICEKEY_NOT_FOUND != ret) {
        return ret;
    }

    //If the key was not found in KVStore we will create it by using random generation and then save it to KVStore
    if (DEVICEKEY_NOT_FOUND == ret) {
        ret = generate_key_by_random(key_buff, actual_size);
        if (DEVICEKEY_SUCCESS != ret) {
            return ret;
        }

        ret = device_inject_root_of_trust(key_buff, actual_size);
        if (DEVICEKEY_SUCCESS != ret) {
            return ret;
        }
    }

    ret = get_derived_key(key_buff, actual_size, salt, isalt_size, output, ikey_type);
    return ret;
}

int DeviceKey::device_inject_root_of_trust(uint32_t *value, size_t isize)
{
    return write_key_to_kvstore(value, isize);
}

int DeviceKey::write_key_to_kvstore(uint32_t *input, size_t isize)
{
    if (DEVICE_KEY_16BYTE != isize && DEVICE_KEY_32BYTE != isize) {
        return DEVICEKEY_INVALID_KEY_SIZE;
    }

    //First we read if key exist. If it is exists, we return DEVICEKEY_ALREADY_EXIST error
    uint32_t read_key[DEVICE_KEY_32BYTE / sizeof(uint32_t)] = {0};
    size_t read_size = DEVICE_KEY_32BYTE;
    int ret = read_key_from_kvstore(read_key, read_size);
    if (DEVICEKEY_SUCCESS == ret) {
        return DEVICEKEY_ALREADY_EXIST;
    }
    if (DEVICEKEY_NOT_FOUND != ret) {
        return ret;
    }

    KVMap &kv_map = KVMap::get_instance();
    KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
    if (inner_store == NULL) {
        return DEVICEKEY_SAVE_FAILED;
    }

    ret = ((TDBStore *)inner_store)->reserved_data_set(input, isize);
    if (MBED_ERROR_WRITE_FAILED == ret) {
        return DEVICEKEY_SAVE_FAILED;
    }

    if (MBED_SUCCESS != ret) {
        return DEVICEKEY_KVSTORE_UNPREDICTED_ERROR;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::read_key_from_kvstore(uint32_t *output, size_t &size)
{
    if (size > (uint16_t) -1) {
        return DEVICEKEY_INVALID_PARAM;
    }

    KVMap &kv_map = KVMap::get_instance();
    KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
    if (inner_store == NULL) {
        return DEVICEKEY_NOT_FOUND;
    }

    int kvStatus = ((TDBStore *)inner_store)->reserved_data_get(output, size);
    if (MBED_ERROR_ITEM_NOT_FOUND == kvStatus) {
        return DEVICEKEY_NOT_FOUND;
    }

    if (MBED_ERROR_READ_FAILED == kvStatus || MBED_ERROR_INVALID_SIZE == kvStatus) {
        return DEVICEKEY_READ_FAILED;
    }

    if (MBED_SUCCESS != kvStatus) {
        return DEVICEKEY_KVSTORE_UNPREDICTED_ERROR;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsigned char *isalt,
                               size_t isalt_size, unsigned char *output, uint32_t ikey_type)
{
    //KDF in counter mode implementation as described in Section 5.1
    //of NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions
    int ret;
    size_t counter = 0;
    char separator = 0x00;
    mbedtls_cipher_context_t ctx;
    unsigned char output_len_enc[ 4 ] = {0};
    unsigned char counter_enc[ 1 ] = {0};

    DEVKEY_WRITE_UINT32_LE(output_len_enc, ikey_type);

    mbedtls_cipher_type_t mbedtls_cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
    if (DEVICE_KEY_32BYTE == ikey_size) {
        mbedtls_cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
    }

    const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(mbedtls_cipher_type);

    do {

        mbedtls_cipher_init(&ctx);
        ret = mbedtls_cipher_setup(&ctx, cipher_info);
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_starts(&ctx, (unsigned char *)ikey_buff, ikey_size * 8);
        if (ret != 0) {
            goto finish;
        }

        DEVKEY_WRITE_UINT8_LE(counter_enc, (counter + 1));

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)counter_enc, sizeof(counter_enc));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, isalt, isalt_size);
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)&separator, sizeof(char));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)&output_len_enc, sizeof(output_len_enc));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_finish(&ctx, output + (DEVICE_KEY_16BYTE * (counter)));
        if (ret != 0) {
            goto finish;
        }

        mbedtls_cipher_free(&ctx);

        counter++;

    } while (DEVICE_KEY_16BYTE * counter < ikey_type);

finish:
    if (DEVICEKEY_SUCCESS != ret) {
        mbedtls_cipher_free(&ctx);
        return DEVICEKEY_ERR_CMAC_GENERIC_FAILURE;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::generate_key_by_random(uint32_t *output, size_t size)
{
    int ret = DEVICEKEY_GENERATE_RANDOM_ERROR;

    if (DEVICE_KEY_16BYTE > size) {
        return DEVICEKEY_BUFFER_TOO_SMALL;
    } else if (DEVICE_KEY_16BYTE != size && DEVICE_KEY_32BYTE != size) {
        return DEVICEKEY_INVALID_PARAM;
    }

#if DEVICE_TRNG
    uint32_t test_buff[DEVICE_KEY_32BYTE / sizeof(int)];
    mbedtls_entropy_context *entropy = new mbedtls_entropy_context;
    mbedtls_entropy_init(entropy);
    memset(output, 0, size);
    memset(test_buff, 0, size);

    ret = mbedtls_entropy_func(entropy, (unsigned char *)output, size);
    if (ret != MBED_SUCCESS || mbedtls_ssl_safer_memcmp(test_buff, (unsigned char *)output, size) == 0) {
        ret = DEVICEKEY_GENERATE_RANDOM_ERROR;
    } else {
        ret = DEVICEKEY_SUCCESS;
    }

    mbedtls_entropy_free(entropy);
    delete entropy;
#endif

    return ret;
}

} // namespace mbed

#endif
#endif

<commit_msg>Adding MBEDTLS_ENTROPY_NV_SEED macro check in device key to allow key derivation when there is no TRNG but there is DRBG<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 *
 * 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 "DeviceKey.h"

#if DEVICEKEY_ENABLED
#include "mbedtls/config.h"
#include "mbedtls/cmac.h"
#include "KVStore.h"
#include "TDBStore.h"
#include "KVMap.h"
#include "kv_config.h"
#include "mbed_wait_api.h"
#include "stdlib.h"
#include "platform/mbed_error.h"
#include <string.h>
#include "entropy.h"
#include "platform_mbed.h"
#include "mbed_trace.h"
#include "ssl_internal.h"

#define TRACE_GROUP "DEVKEY"

#if !defined(MBEDTLS_CMAC_C)
#error [NOT_SUPPORTED] MBEDTLS_CMAC_C needs to be enabled for this driver
#else

namespace mbed {

#define DEVKEY_WRITE_UINT32_LE( dst, src )                              \
    do                                                                  \
    {                                                                   \
        (dst)[0] = ( (src) >> 0 ) & 0xFF;                               \
        (dst)[1] = ( (src) >> 8 ) & 0xFF;                               \
        (dst)[2] = ( (src) >> 16 ) & 0xFF;                              \
        (dst)[3] = ( (src) >> 24 ) & 0xFF;                              \
    } while( 0 )

#define DEVKEY_WRITE_UINT8_LE( dst, src )                               \
    do                                                                  \
    {                                                                   \
        (dst)[0] = (src) & 0xFF;                                        \
    } while( 0 )

DeviceKey::DeviceKey()
{
    int ret = kv_init_storage_config();
    if (ret != MBED_SUCCESS) {
        tr_error("DeviceKey: Fail to initialize KvStore configuration.");
    }
    return;
}

DeviceKey::~DeviceKey()
{
    return;
}

int DeviceKey::generate_derived_key(const unsigned char *salt, size_t isalt_size, unsigned char *output,
                                    uint16_t ikey_type)
{
    uint32_t key_buff[DEVICE_KEY_32BYTE / sizeof(uint32_t)];
    size_t actual_size = DEVICE_KEY_32BYTE;

    if (DEVICE_KEY_16BYTE != ikey_type && DEVICE_KEY_32BYTE != ikey_type) {
        return DEVICEKEY_INVALID_KEY_TYPE;
    }

    actual_size = DEVICE_KEY_16BYTE != ikey_type ? DEVICE_KEY_32BYTE : DEVICE_KEY_16BYTE;

    //First try to read the key from KVStore
    int ret = read_key_from_kvstore(key_buff, actual_size);
    if (DEVICEKEY_SUCCESS != ret && DEVICEKEY_NOT_FOUND != ret) {
        return ret;
    }

    //If the key was not found in KVStore we will create it by using random generation and then save it to KVStore
    if (DEVICEKEY_NOT_FOUND == ret) {
        ret = generate_key_by_random(key_buff, actual_size);
        if (DEVICEKEY_SUCCESS != ret) {
            return ret;
        }

        ret = device_inject_root_of_trust(key_buff, actual_size);
        if (DEVICEKEY_SUCCESS != ret) {
            return ret;
        }
    }

    ret = get_derived_key(key_buff, actual_size, salt, isalt_size, output, ikey_type);
    return ret;
}

int DeviceKey::device_inject_root_of_trust(uint32_t *value, size_t isize)
{
    return write_key_to_kvstore(value, isize);
}

int DeviceKey::write_key_to_kvstore(uint32_t *input, size_t isize)
{
    if (DEVICE_KEY_16BYTE != isize && DEVICE_KEY_32BYTE != isize) {
        return DEVICEKEY_INVALID_KEY_SIZE;
    }

    //First we read if key exist. If it is exists, we return DEVICEKEY_ALREADY_EXIST error
    uint32_t read_key[DEVICE_KEY_32BYTE / sizeof(uint32_t)] = {0};
    size_t read_size = DEVICE_KEY_32BYTE;
    int ret = read_key_from_kvstore(read_key, read_size);
    if (DEVICEKEY_SUCCESS == ret) {
        return DEVICEKEY_ALREADY_EXIST;
    }
    if (DEVICEKEY_NOT_FOUND != ret) {
        return ret;
    }

    KVMap &kv_map = KVMap::get_instance();
    KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
    if (inner_store == NULL) {
        return DEVICEKEY_SAVE_FAILED;
    }

    ret = ((TDBStore *)inner_store)->reserved_data_set(input, isize);
    if (MBED_ERROR_WRITE_FAILED == ret) {
        return DEVICEKEY_SAVE_FAILED;
    }

    if (MBED_SUCCESS != ret) {
        return DEVICEKEY_KVSTORE_UNPREDICTED_ERROR;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::read_key_from_kvstore(uint32_t *output, size_t &size)
{
    if (size > (uint16_t) -1) {
        return DEVICEKEY_INVALID_PARAM;
    }

    KVMap &kv_map = KVMap::get_instance();
    KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
    if (inner_store == NULL) {
        return DEVICEKEY_NOT_FOUND;
    }

    int kvStatus = ((TDBStore *)inner_store)->reserved_data_get(output, size);
    if (MBED_ERROR_ITEM_NOT_FOUND == kvStatus) {
        return DEVICEKEY_NOT_FOUND;
    }

    if (MBED_ERROR_READ_FAILED == kvStatus || MBED_ERROR_INVALID_SIZE == kvStatus) {
        return DEVICEKEY_READ_FAILED;
    }

    if (MBED_SUCCESS != kvStatus) {
        return DEVICEKEY_KVSTORE_UNPREDICTED_ERROR;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsigned char *isalt,
                               size_t isalt_size, unsigned char *output, uint32_t ikey_type)
{
    //KDF in counter mode implementation as described in Section 5.1
    //of NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions
    int ret;
    size_t counter = 0;
    char separator = 0x00;
    mbedtls_cipher_context_t ctx;
    unsigned char output_len_enc[ 4 ] = {0};
    unsigned char counter_enc[ 1 ] = {0};

    DEVKEY_WRITE_UINT32_LE(output_len_enc, ikey_type);

    mbedtls_cipher_type_t mbedtls_cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
    if (DEVICE_KEY_32BYTE == ikey_size) {
        mbedtls_cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
    }

    const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(mbedtls_cipher_type);

    do {

        mbedtls_cipher_init(&ctx);
        ret = mbedtls_cipher_setup(&ctx, cipher_info);
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_starts(&ctx, (unsigned char *)ikey_buff, ikey_size * 8);
        if (ret != 0) {
            goto finish;
        }

        DEVKEY_WRITE_UINT8_LE(counter_enc, (counter + 1));

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)counter_enc, sizeof(counter_enc));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, isalt, isalt_size);
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)&separator, sizeof(char));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_update(&ctx, (unsigned char *)&output_len_enc, sizeof(output_len_enc));
        if (ret != 0) {
            goto finish;
        }

        ret = mbedtls_cipher_cmac_finish(&ctx, output + (DEVICE_KEY_16BYTE * (counter)));
        if (ret != 0) {
            goto finish;
        }

        mbedtls_cipher_free(&ctx);

        counter++;

    } while (DEVICE_KEY_16BYTE * counter < ikey_type);

finish:
    if (DEVICEKEY_SUCCESS != ret) {
        mbedtls_cipher_free(&ctx);
        return DEVICEKEY_ERR_CMAC_GENERIC_FAILURE;
    }

    return DEVICEKEY_SUCCESS;
}

int DeviceKey::generate_key_by_random(uint32_t *output, size_t size)
{
    int ret = DEVICEKEY_GENERATE_RANDOM_ERROR;

    if (DEVICE_KEY_16BYTE > size) {
        return DEVICEKEY_BUFFER_TOO_SMALL;
    } else if (DEVICE_KEY_16BYTE != size && DEVICE_KEY_32BYTE != size) {
        return DEVICEKEY_INVALID_PARAM;
    }

#if defined(DEVICE_TRNG) || defined(MBEDTLS_ENTROPY_NV_SEED)
    uint32_t test_buff[DEVICE_KEY_32BYTE / sizeof(int)];
    mbedtls_entropy_context *entropy = new mbedtls_entropy_context;
    mbedtls_entropy_init(entropy);
    memset(output, 0, size);
    memset(test_buff, 0, size);

    ret = mbedtls_entropy_func(entropy, (unsigned char *)output, size);
    if (ret != MBED_SUCCESS || mbedtls_ssl_safer_memcmp(test_buff, (unsigned char *)output, size) == 0) {
        ret = DEVICEKEY_GENERATE_RANDOM_ERROR;
    } else {
        ret = DEVICEKEY_SUCCESS;
    }

    mbedtls_entropy_free(entropy);
    delete entropy;

#endif

    return ret;
}

} // namespace mbed

#endif
#endif

<|endoftext|>


<commit_before>#include "t_xl_interpreter.h"
#include "xl_instruction.h"
#include "xl_interpreter.h"

using namespace std;
using namespace xl;

static const double TOLERANCE = 0.00001;

void TestInterpreter::emptyProgramInvalid() {
    Program program;
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(!interp.run());
}

void TestInterpreter::pushAddsInstructionToStack() {
    const double operand = 1.0;
    Program program = {
        { PUSH, operand }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, interp.result(), TOLERANCE);
}

void TestInterpreter::nopDoesNothing() {
    const double operand = 5.0;
    Program program = {
        { PUSH, operand },
        { NOP }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(operand, interp.result(), TOLERANCE);
}

void TestInterpreter::popRemovesFromStack() {
    const double operand = 5.0;
    Program program = {
        { PUSH, operand },
        { PUSH, 42.0    },
        { POP           }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(operand, interp.result(), TOLERANCE);
}

void TestInterpreter::popEmptyStackNotValid() {
    Program program = {
        { POP }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(!interp.run());
}

void TestInterpreter::equalOperatorComparesTwoValues() {
    const double lhs = 3.0;
    const double rhs = 3.0;
    Program program = {
        { PUSH, lhs },
        { PUSH, rhs },
        { EQ }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_EQUAL(lhs == rhs, static_cast<bool>(interp.result()));
}

//------------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION(TestInterpreter);
<commit_msg>Generic test for equals operator<commit_after>#include "t_xl_interpreter.h"
#include "xl_instruction.h"
#include "xl_interpreter.h"
#include <vector>
#include <utility>

using namespace std;
using namespace xl;

static const double TOLERANCE = 0.00001;

void TestInterpreter::emptyProgramInvalid() {
    Program program;
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(!interp.run());
}

void TestInterpreter::pushAddsInstructionToStack() {
    const double operand = 1.0;
    Program program = {
        { PUSH, operand }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, interp.result(), TOLERANCE);
}

void TestInterpreter::nopDoesNothing() {
    const double operand = 5.0;
    Program program = {
        { PUSH, operand },
        { NOP }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(operand, interp.result(), TOLERANCE);
}

void TestInterpreter::popRemovesFromStack() {
    const double operand = 5.0;
    Program program = {
        { PUSH, operand },
        { PUSH, 42.0    },
        { POP           }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(interp.run());
    CPPUNIT_ASSERT_DOUBLES_EQUAL(operand, interp.result(), TOLERANCE);
}

void TestInterpreter::popEmptyStackNotValid() {
    Program program = {
        { POP }
    };
    Interpreter interp(move(program));
    CPPUNIT_ASSERT(!interp.run());
}

void TestInterpreter::equalOperatorComparesTwoValues() {
    const vector<pair<double, double>> cases = {
        { 3.0, 3.0 },
        { 2.0, 3.0 },
        { 3.0, 2.0 },
    };

    for (auto&& c: cases) {
        auto&& lhs = get<0>(c);
        auto&& rhs = get<1>(c);
        Program program = {
            { PUSH, lhs },
            { PUSH, rhs },
            { EQ }
        };
        Interpreter interp(move(program));
        CPPUNIT_ASSERT(interp.run());
        CPPUNIT_ASSERT_EQUAL(lhs == rhs, static_cast<bool>(interp.result()));
    }
}

//------------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION(TestInterpreter);
<|endoftext|>


<commit_before>#ifndef _FALCON_UTILITY_MAKER_HPP
#define _FALCON_UTILITY_MAKER_HPP

#ifdef __GXX_EXPERIMENTAL_CXX0X__
# include <utility>
# include <falcon/utility/detail/construct_category.hpp>
#endif

namespace falcon {

#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _Tp, typename _Tag>
struct __maker
{
	constexpr __maker()
	{}

	template<typename _Up, typename _Tag2>
	constexpr __maker(const __maker<_Up, _Tag2>&)
	{}

	_Tp operator()() const
	{
		return _Tp();
	}

	_Tp operator()(const _Tp& v) const
	{
		return _Tp(v);
	}

	template<typename... _Args>
	_Tp operator()(_Args&&... args) const
	{
		return _Tp{std::forward<_Args>(args)...};
	}
};

template<typename _Tp>
struct __maker<_Tp, ::falcon::detail::initilizer_list_construct_tag>
{
	constexpr __maker()
	{}

	template<typename _Up, typename _Tag>
	constexpr __maker(const __maker<_Up, _Tag>&)
	{}

	_Tp operator()() const
	{
		return _Tp();
	}

	_Tp operator()(const _Tp& v) const
	{
		return _Tp(v);
	}

	template<typename... _Args>
	_Tp operator()(_Args&&... args) const
	{
		return _Tp{{std::forward<_Args>(args)...}};
	}
};

///wrapper of construct object
template<typename _Tp>
struct maker
: __maker< _Tp, typename ::falcon::detail::construct_category<_Tp>::type>
{};

#else

///wrapper of construct object
template<typename _Tp>
struct maker
{
	maker()
	{}

	template<typename _Up>
	maker(const maker<_Up>&)
	{}

	_Tp operator()() const
	{
		return _Tp();
	}

	_Tp operator()(const _Tp& v) const
	{
		return _Tp(v);
	}
};
#endif

}

#endif
<commit_msg>simplification of maker<> and create late_maker<><commit_after>#ifndef _FALCON_UTILITY_MAKER_HPP
#define _FALCON_UTILITY_MAKER_HPP

#ifdef __GXX_EXPERIMENTAL_CXX0X__
# include <utility>
# include <falcon/utility/detail/construct_category.hpp>
#endif
#include <falcon/c++/constexpr.hpp>

namespace falcon {

#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _T, typename _Tag = typename detail::construct_category<_T>::type>
struct __delegate_maker
{
	template<typename... _Args>
	constexpr static _T __impl(_Args&&... args)
	{ return _T{std::forward<_Args>(args)...}; }
};

template<typename _T>
struct __delegate_maker<_T, ::falcon::detail::initilizer_list_construct_tag>
{
	template<typename... _Args>
	constexpr static _T __impl(_Args&&... args)
	{ return _T{{std::forward<_Args>(args)...}}; }
};

///wrapper of construct object
template <template<typename...> class _Template>
struct late_maker
{
	constexpr late_maker()
	{}

	template<template<typename...> class _UTemplate>
	constexpr late_maker(const late_maker<_UTemplate>&)
	{}

	constexpr _Template<> operator()() const
	{ return _Template<>(); }

	template<typename... _Args>
	constexpr _Template<_Args...> operator()(_Args&&... args) const
	{ return __delegate_maker<_Template<_Args...>>::__impl(args...); }
};
#endif

///wrapper of construct object
template<typename _Tp>
struct maker
{
	CPP_CONSTEXPR maker()
	{}

	template<typename _Up>
	CPP_CONSTEXPR maker(const maker<_Up>&)
	{}

	CPP_CONSTEXPR _Tp operator()() const
	{ return _Tp(); }

	CPP_CONSTEXPR _Tp operator()(const _Tp& v) const
	{ return _Tp(v); }

	template<typename _U>
	CPP_CONSTEXPR _Tp operator()(const _U& v) const
	{ return _Tp(v); }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
	template<typename... _Args>
	constexpr _Tp operator()(_Args&&... args) const
	{ return __delegate_maker<_Tp>::__impl(args...); }
#endif
};

}

#endif
<|endoftext|>


<commit_before>/* Basic example of diagonalization of a 2D tight-binding model with t = 1 and
 * mu = -1. Lattice with edges and a size of 20x20 sites.
 */

#include <iostream>
#include <complex>
#include "Model.h"
#include "FileWriter.h"
#include "PropertyExtractor.h"
#include "DiagonalizationSolver.h"

using namespace std;

const complex<double> i(0, 1);

int main(int argc, char **argv){
	//Lattice size
	const int SIZE_X = 20;
	const int SIZE_Y = 20;

	//Parameters
	complex<double> mu = -1.0;
	complex<double> t = 1.0;

	//Create model and set up hopping parameters
	Model model;
	for(int x = 0; x < SIZE_X; x++){
		for(int y = 0; y < SIZE_Y; y++){
			for(int s = 0; s < 2; s++){
				//Add hopping amplitudes corresponding to chemical potential
				model.addHA(HoppingAmplitude(-mu,	{x, y, s},	{x, y, s}));

				//Add hopping parameters corresponding to t
				if(x+1 < SIZE_X)
					model.addHAAndHC(HoppingAmplitude(-t,	{(x+1)%SIZE_X, y, s},	{x, y, s}));
				if(y+1 < SIZE_Y)
					model.addHAAndHC(HoppingAmplitude(-t,	{x, (y+1)%SIZE_Y, s},	{x, y, s}));
			}
		}
	}

	//Construct model
	model.construct();

	//Setup and run DiagonalizationSolver
	DiagonalizationSolver dSolver;
	dSolver.setModel(&model);
	dSolver.run();

	//Set filename and remove any file already in the folder
	FileWriter::setFileName("TBTKResults.h5");
	FileWriter::clear();

	//Create PropertyExtractor
	PropertyExtractor pe(&dSolver);

	//Extract eigenvalues and write these to file
	double *ev = pe.getEV();
	FileWriter::writeEV(ev, model.getBasisSize());
	delete [] ev;

	return 0;
}
<commit_msg>Added extraction of DOS<commit_after>/* Basic example of diagonalization of a 2D tight-binding model with t = 1 and
 * mu = -1. Lattice with edges and a size of 20x20 sites.
 */

#include <iostream>
#include <complex>
#include "Model.h"
#include "FileWriter.h"
#include "PropertyExtractor.h"
#include "DiagonalizationSolver.h"

using namespace std;

const complex<double> i(0, 1);

int main(int argc, char **argv){
	//Lattice size
	const int SIZE_X = 40;
	const int SIZE_Y = 40;

	//Parameters
	complex<double> mu = -1.0;
	complex<double> t = 1.0;

	//Create model and set up hopping parameters
	Model model;
	for(int x = 0; x < SIZE_X; x++){
		for(int y = 0; y < SIZE_Y; y++){
			for(int s = 0; s < 2; s++){
				//Add hopping amplitudes corresponding to chemical potential
				model.addHA(HoppingAmplitude(-mu,	{x, y, s},	{x, y, s}));

				//Add hopping parameters corresponding to t
				if(x+1 < SIZE_X)
					model.addHAAndHC(HoppingAmplitude(-t,	{(x+1)%SIZE_X, y, s},	{x, y, s}));
				if(y+1 < SIZE_Y)
					model.addHAAndHC(HoppingAmplitude(-t,	{x, (y+1)%SIZE_Y, s},	{x, y, s}));
			}
		}
	}

	//Construct model
	model.construct();

	//Setup and run DiagonalizationSolver
	DiagonalizationSolver dSolver;
	dSolver.setModel(&model);
	dSolver.run();

	//Set filename and remove any file already in the folder
	FileWriter::setFileName("TBTKResults.h5");
	FileWriter::clear();

	//Create PropertyExtractor
	PropertyExtractor pe(&dSolver);

	//Extract eigenvalues and write these to file
	double *ev = pe.getEV();
	FileWriter::writeEV(ev, model.getBasisSize());
	delete [] ev;

	//Extract DOS and write to file
	const double UPPER_LIMIT = 6.;
	const double LOWER_LIMIT = -4.;
	const int RESOLUTION = 1000;
	double *dos = pe.calculateDOS(UPPER_LIMIT, LOWER_LIMIT, RESOLUTION);
	FileWriter::writeDOS(dos, UPPER_LIMIT, LOWER_LIMIT, RESOLUTION);
	delete [] dos;

	return 0;
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 "shaka/sdl_frame_drawer.h"

#include <SDL2/SDL.h>

#include <list>
#include <unordered_set>

#include "src/util/macros.h"

namespace shaka {

namespace {

constexpr const size_t kMaxTextures = 8;

struct TextureInfo {
  TextureInfo(SDL_Texture* texture, uint32_t pixel_format, int width,
              int height)
      : texture(texture),
        pixel_format(pixel_format),
        width(width),
        height(height) {}

  ~TextureInfo() {
    SDL_DestroyTexture(texture);
  }

  SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(TextureInfo);

  SDL_Texture* texture;
  uint32_t pixel_format;
  int width;
  int height;
};

Uint32 SdlPixelFormatFromPublic(
    variant<media::PixelFormat, media::SampleFormat> format) {
  switch (get<media::PixelFormat>(format)) {
#if SDL_VERSION_ATLEAST(2, 0, 4)
    case media::PixelFormat::NV12:
      return SDL_PIXELFORMAT_NV12;
#endif
    case media::PixelFormat::YUV420P:
      return SDL_PIXELFORMAT_IYUV;
    case media::PixelFormat::RGB24:
      return SDL_PIXELFORMAT_RGB24;

    default:
      return SDL_PIXELFORMAT_UNKNOWN;
  }
}

}  // namespace

class SdlFrameDrawer::Impl {
 public:
  Impl() : renderer_(nullptr) {}
  ~Impl() {}

  SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(Impl);

  void SetRenderer(SDL_Renderer* renderer) {
    textures_.clear();
    texture_formats_.clear();
    renderer_ = renderer;

    if (renderer) {
      SDL_RendererInfo info;
      if (SDL_GetRendererInfo(renderer, &info) == 0) {
        texture_formats_.insert(
            info.texture_formats,
            info.texture_formats + info.num_texture_formats);
      }
      if (texture_formats_.empty()) {
        LOG(ERROR) << "No supported texture formats";
      }
    }
  }

  SDL_Texture* Draw(std::shared_ptr<media::DecodedFrame> frame) {
    if (!frame)
      return nullptr;

    auto sdl_pix_fmt = SdlPixelFormatFromPublic(frame->format);
    if (sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ||
        texture_formats_.count(sdl_pix_fmt) == 0) {
      return nullptr;
    }

    SDL_Texture* texture = GetTexture(sdl_pix_fmt, frame->stream_info->width,
                                      frame->stream_info->height);
    if (!texture)
      return nullptr;

    if (!DrawOntoTexture(frame, texture, sdl_pix_fmt))
      return nullptr;

    return texture;
  }

 private:
  bool DrawOntoTexture(std::shared_ptr<media::DecodedFrame> frame,
                       SDL_Texture* texture, Uint32 sdl_pix_fmt) {
    const uint8_t* const* frame_data = frame->data.data();
    const size_t* frame_linesize = frame->linesize.data();

    if (sdl_pix_fmt == SDL_PIXELFORMAT_IYUV) {
      if (SDL_UpdateYUVTexture(
              texture, nullptr, frame_data[0], frame_linesize[0], frame_data[1],
              frame_linesize[1], frame_data[2], frame_linesize[2]) < 0) {
        LOG(ERROR) << "Error updating texture: " << SDL_GetError();
        return false;
      }
#if SDL_VERSION_ATLEAST(2, 0, 4)
    } else if (sdl_pix_fmt == SDL_PIXELFORMAT_NV12 ||
               sdl_pix_fmt == SDL_PIXELFORMAT_NV21) {
      uint8_t* pixels;
      int pitch;
      if (SDL_LockTexture(texture, nullptr, reinterpret_cast<void**>(&pixels),
                          &pitch) < 0) {
        LOG(ERROR) << "Error locking texture: " << SDL_GetError();
        return false;
      }

      if (static_cast<size_t>(pitch) == frame_linesize[0]) {
        // TODO: Sometimes there is a green bar at the bottom.
        const size_t size0 = pitch * frame->stream_info->height;
        memcpy(pixels, frame_data[0], size0);
        memcpy(pixels + size0, frame_data[1], size0 / 2);
      } else {
        // FFmpeg may add padding to the rows, so we need to drop it by manually
        // copying each line.
        DCHECK_GE(frame_linesize[0], pitch);
        const int min_width = std::min<size_t>(pitch, frame_linesize[0]);
        for (uint32_t row = 0; row < frame->stream_info->height; row++) {
          uint8_t* dest = pixels + pitch * row;
          const uint8_t* src = frame_data[0] + frame_linesize[0] * row;
          memcpy(dest, src, min_width);
        }
        for (uint32_t row = 0; row < frame->stream_info->height / 2; row++) {
          uint8_t* dest = pixels + pitch * (row + frame->stream_info->height);
          const uint8_t* src = frame_data[1] + frame_linesize[1] * row;
          memcpy(dest, src, min_width);
        }
      }

      SDL_UnlockTexture(texture);
#endif
    } else {
      if (SDL_UpdateTexture(texture, nullptr, frame_data[0],
                            frame_linesize[0]) < 0) {
        LOG(ERROR) << "Error updating texture: " << SDL_GetError();
        return false;
      }
    }

    return true;
  }

  SDL_Texture* GetTexture(Uint32 pixel_format, int width, int height) {
    if (!renderer_)
      return nullptr;

    for (auto it = textures_.begin(); it != textures_.end(); it++) {
      if (it->pixel_format == pixel_format && it->width == width &&
          it->height == height) {
        if (std::next(it) != textures_.end()) {
          // Move the texture to the end so elements at the beginning are ones
          // that were least-recently used.
          textures_.splice(textures_.end(), textures_, it);
        }

        return it->texture;
      }
    }

    while (!textures_.empty() && textures_.size() >= kMaxTextures) {
      textures_.erase(textures_.begin());
    }

    SDL_Texture* texture = SDL_CreateTexture(
        renderer_, pixel_format, SDL_TEXTUREACCESS_STREAMING, width, height);
    if (texture)
      textures_.emplace_back(texture, pixel_format, width, height);
    else
      LOG(ERROR) << "Error creating texture: " << SDL_GetError();

    return texture;
  }

  std::list<TextureInfo> textures_;
  std::unordered_set<Uint32> texture_formats_;
  SDL_Renderer* renderer_;
};

SdlFrameDrawer::SdlFrameDrawer() : impl_(new Impl) {}
SdlFrameDrawer::SdlFrameDrawer(SdlFrameDrawer&&) = default;
SdlFrameDrawer::~SdlFrameDrawer() {}
SdlFrameDrawer& SdlFrameDrawer::operator=(SdlFrameDrawer&&) = default;

void SdlFrameDrawer::SetRenderer(SDL_Renderer* renderer) {
  impl_->SetRenderer(renderer);
}

SDL_Texture* SdlFrameDrawer::Draw(std::shared_ptr<media::DecodedFrame> frame) {
  return impl_->Draw(frame);
}

}  // namespace shaka
<commit_msg>Fix video rendering on Mac.<commit_after>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 "shaka/sdl_frame_drawer.h"

#include <SDL2/SDL.h>
#ifdef __APPLE__
#  include <VideoToolbox/VideoToolbox.h>
#endif

#include <list>
#include <unordered_set>

#include "src/util/macros.h"

namespace shaka {

namespace {

constexpr const size_t kMaxTextures = 8;

struct TextureInfo {
  TextureInfo(SDL_Texture* texture, uint32_t pixel_format, int width,
              int height)
      : texture(texture),
        pixel_format(pixel_format),
        width(width),
        height(height) {}

  ~TextureInfo() {
    SDL_DestroyTexture(texture);
  }

  SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(TextureInfo);

  SDL_Texture* texture;
  uint32_t pixel_format;
  int width;
  int height;
};

Uint32 SdlPixelFormatFromPublic(
    variant<media::PixelFormat, media::SampleFormat> format) {
  switch (get<media::PixelFormat>(format)) {
#if SDL_VERSION_ATLEAST(2, 0, 4)
#  ifdef __APPLE__
    case media::PixelFormat::VideoToolbox:
#  endif
    case media::PixelFormat::NV12:
      return SDL_PIXELFORMAT_NV12;
#endif
    case media::PixelFormat::YUV420P:
      return SDL_PIXELFORMAT_IYUV;
    case media::PixelFormat::RGB24:
      return SDL_PIXELFORMAT_RGB24;

    default:
      LOG(DFATAL) << "Unsupported pixel format: " << format;
      return SDL_PIXELFORMAT_UNKNOWN;
  }
}

}  // namespace

class SdlFrameDrawer::Impl {
 public:
  Impl() : renderer_(nullptr) {}
  ~Impl() {}

  SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(Impl);

  void SetRenderer(SDL_Renderer* renderer) {
    textures_.clear();
    texture_formats_.clear();
    renderer_ = renderer;

    if (renderer) {
      SDL_RendererInfo info;
      if (SDL_GetRendererInfo(renderer, &info) == 0) {
        texture_formats_.insert(
            info.texture_formats,
            info.texture_formats + info.num_texture_formats);
      }
      if (texture_formats_.empty()) {
        LOG(DFATAL) << "No supported texture formats";
      }
    }
  }

  SDL_Texture* Draw(std::shared_ptr<media::DecodedFrame> frame) {
    if (!frame)
      return nullptr;

    auto sdl_pix_fmt = SdlPixelFormatFromPublic(frame->format);
    if (sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ||
        texture_formats_.count(sdl_pix_fmt) == 0) {
      return nullptr;
    }

    SDL_Texture* texture = GetTexture(sdl_pix_fmt, frame->stream_info->width,
                                      frame->stream_info->height);
    if (!texture)
      return nullptr;

    if (!DrawOntoTexture(frame, texture, sdl_pix_fmt))
      return nullptr;

    return texture;
  }

 private:
  bool DrawOntoTexture(std::shared_ptr<media::DecodedFrame> frame,
                       SDL_Texture* texture, Uint32 sdl_pix_fmt) {
    const uint8_t* const* frame_data = frame->data.data();
    const size_t* frame_linesize = frame->linesize.data();

    if (sdl_pix_fmt == SDL_PIXELFORMAT_IYUV) {
      if (SDL_UpdateYUVTexture(
              texture, nullptr, frame_data[0], frame_linesize[0], frame_data[1],
              frame_linesize[1], frame_data[2], frame_linesize[2]) < 0) {
        LOG(DFATAL) << "Error updating texture: " << SDL_GetError();
        return false;
      }
#if SDL_VERSION_ATLEAST(2, 0, 4)
#  ifdef __APPLE__
    } else if (get<media::PixelFormat>(frame->format) ==
               media::PixelFormat::VideoToolbox) {
      auto* pix_buf = reinterpret_cast<CVPixelBufferRef>(
          const_cast<uint8_t*>(frame->data[0]));
      uint8_t* pixels;
      int pitch;
      if (SDL_LockTexture(texture, nullptr, reinterpret_cast<void**>(&pixels),
                          &pitch) < 0) {
        LOG(DFATAL) << "Error locking texture: " << SDL_GetError();
        return false;
      }
      if (static_cast<size_t>(pitch) !=
              CVPixelBufferGetBytesPerRowOfPlane(pix_buf, 0) ||
          !CVPixelBufferIsPlanar(pix_buf) ||
          CVPixelBufferGetPlaneCount(pix_buf) != 2) {
        LOG(DFATAL) << "Invalid pixel buffer";
        SDL_UnlockTexture(texture);
        return false;
      }
      if (CVPixelBufferLockBaseAddress(pix_buf, kCVPixelBufferLock_ReadOnly) !=
          0) {
        LOG(DFATAL) << "Error locking pixel_buffer";
        SDL_UnlockTexture(texture);
        return false;
      }

      const size_t size0 = pitch * frame->stream_info->height;
      memcpy(pixels, CVPixelBufferGetBaseAddressOfPlane(pix_buf, 0), size0);
      memcpy(pixels + size0, CVPixelBufferGetBaseAddressOfPlane(pix_buf, 1),
             size0 / 2);

      CVPixelBufferUnlockBaseAddress(pix_buf, kCVPixelBufferLock_ReadOnly);
      SDL_UnlockTexture(texture);
#  endif
    } else if (sdl_pix_fmt == SDL_PIXELFORMAT_NV12 ||
               sdl_pix_fmt == SDL_PIXELFORMAT_NV21) {
      uint8_t* pixels;
      int pitch;
      if (SDL_LockTexture(texture, nullptr, reinterpret_cast<void**>(&pixels),
                          &pitch) < 0) {
        LOG(DFATAL) << "Error locking texture: " << SDL_GetError();
        return false;
      }

      if (static_cast<size_t>(pitch) == frame_linesize[0]) {
        // TODO: Sometimes there is a green bar at the bottom.
        const size_t size0 = pitch * frame->stream_info->height;
        memcpy(pixels, frame_data[0], size0);
        memcpy(pixels + size0, frame_data[1], size0 / 2);
      } else {
        // FFmpeg may add padding to the rows, so we need to drop it by manually
        // copying each line.
        DCHECK_GE(frame_linesize[0], pitch);
        const int min_width = std::min<size_t>(pitch, frame_linesize[0]);
        for (uint32_t row = 0; row < frame->stream_info->height; row++) {
          uint8_t* dest = pixels + pitch * row;
          const uint8_t* src = frame_data[0] + frame_linesize[0] * row;
          memcpy(dest, src, min_width);
        }
        for (uint32_t row = 0; row < frame->stream_info->height / 2; row++) {
          uint8_t* dest = pixels + pitch * (row + frame->stream_info->height);
          const uint8_t* src = frame_data[1] + frame_linesize[1] * row;
          memcpy(dest, src, min_width);
        }
      }

      SDL_UnlockTexture(texture);
#endif
    } else {
      if (SDL_UpdateTexture(texture, nullptr, frame_data[0],
                            frame_linesize[0]) < 0) {
        LOG(DFATAL) << "Error updating texture: " << SDL_GetError();
        return false;
      }
    }

    return true;
  }

  SDL_Texture* GetTexture(Uint32 pixel_format, int width, int height) {
    if (!renderer_)
      return nullptr;

    for (auto it = textures_.begin(); it != textures_.end(); it++) {
      if (it->pixel_format == pixel_format && it->width == width &&
          it->height == height) {
        if (std::next(it) != textures_.end()) {
          // Move the texture to the end so elements at the beginning are ones
          // that were least-recently used.
          textures_.splice(textures_.end(), textures_, it);
        }

        return it->texture;
      }
    }

    while (!textures_.empty() && textures_.size() >= kMaxTextures) {
      textures_.erase(textures_.begin());
    }

    SDL_Texture* texture = SDL_CreateTexture(
        renderer_, pixel_format, SDL_TEXTUREACCESS_STREAMING, width, height);
    if (texture)
      textures_.emplace_back(texture, pixel_format, width, height);
    else
      LOG(DFATAL) << "Error creating texture: " << SDL_GetError();

    return texture;
  }

  std::list<TextureInfo> textures_;
  std::unordered_set<Uint32> texture_formats_;
  SDL_Renderer* renderer_;
};

SdlFrameDrawer::SdlFrameDrawer() : impl_(new Impl) {}
SdlFrameDrawer::SdlFrameDrawer(SdlFrameDrawer&&) = default;
SdlFrameDrawer::~SdlFrameDrawer() {}
SdlFrameDrawer& SdlFrameDrawer::operator=(SdlFrameDrawer&&) = default;

void SdlFrameDrawer::SetRenderer(SDL_Renderer* renderer) {
  impl_->SetRenderer(renderer);
}

SDL_Texture* SdlFrameDrawer::Draw(std::shared_ptr<media::DecodedFrame> frame) {
  return impl_->Draw(frame);
}

}  // namespace shaka
<|endoftext|>


<commit_before>#ifndef HMLIB_ALGORITHM_ALGORITHM_INC
#define HMLIB_ALGORITHM_ALGORITHM_INC 100
#
#include<utility>
#include<algorithm>
namespace hmLib{
	/*! @brief Remove elements from the given range with allowing change order of elements (value version).
	This is altenative faster algorithm of std::remove, but after applying this function the elements order can be changed.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Value The removing value from the range
	@return End of non-removed elemetns */
	template<typename bidirectional_iterator, typename type>
	bidirectional_iterator unstable_remove(bidirectional_iterator Beg, bidirectional_iterator End, const type& Value) {
		while(Beg!=End) {
			if(*Beg==Value) {
				--End;
				while(Beg!=End) {
					if(*End!=Value) {
						*Beg = std::move(*End);
						++Beg;
						break;
					} else {
						--End;
					}
				}
			} else {
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range with allowing change order of elements (functor version).
	This is altenative faster algorithm of std::remove_if, but after applying this function the elements order can be changed.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Cond All elemtns are evaluated as Cond(*Beg). If true is returned, the element is removed from the range.
	@return End of non-removed elemetns */
	template<typename bidirectional_iterator, typename condition>
	bidirectional_iterator unstable_remove_if(bidirectional_iterator Beg, bidirectional_iterator End, condition Cond) {
		while(Beg!=End) {
			if(Cond(*Beg)) {
				--End;
				while(Beg!=End) {
					if(!Cond(*End)) {
						*Beg = std::move(*End);
						++Beg;
						break;
					} else {
						--End;
					}
				}
			} else {
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range by using swap function instead of move (value version).
	This is altenative algorithm of std::remove, but use std::swap for moving elements.
	This means that the removed elements can be still accessible.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Value The removing value from the range
	@return End of non-removed elemetns */
	template<typename forward_iterator, typename type>
	forward_iterator swap_remove(forward_iterator Beg, forward_iterator End, const type& Value) {
		for(auto Itr = Beg; Itr!=End; ++Itr) {
			if(*Itr!=Value) {
				if(Beg!=Itr)std::swap(*Beg, *Itr);
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range by using swap function instead of move (functor version).
	This is altenative algorithm of std::remove_if, but use std::swap for moving elements.
	This means that the removed elements can be still accessible.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Cond All elemtns are evaluated as Cond(*Beg). If true is returned, the element is removed from the range.
	@return End of non-removed elemetns */
	template<typename forward_iterator, typename condition>
	forward_iterator swap_remove_if(forward_iterator Beg, forward_iterator End, condition Cond) {
		//Itr: condition checked element
		//Beg: end of remaining elements

		auto Itr = Beg;
		//Beg==Itr as long as Cond is false
		while(Itr!=End) {
			if(Cond(*Itr)){
				++Itr;
				break;
			}
			++Beg;
			++Itr;
		}
		//Beg!=Itr
		while(Itr!=End){
			if(!Cond(*Itr)){
				std::swap(*Beg, *Itr);
				++Beg;
			}
			++Itr;
		}
		return Beg;
	}

	template<typename Iterator, typename Transform>
	std::pair<decltype(std::declval<Transform>()(*std::declval<Iterator>())), Iterator>
	transform_max_element(Iterator Beg, Iterator End, Transform Fn){
		auto Max = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::lowest();
		Iterator MaxItr = End;

		for(; Beg != End; ++Beg){
			auto Val = Fn(*Beg);
			if(Val > Max){
				Max = Val;
				MaxItr = Beg;
			}
		}
		return std::make_pair(Max,MaxItr);
	}
	template<typename Iterator, typename Transform>
	std::pair<decltype(std::declval<Transform>()(*std::declval<Iterator>())), Iterator>
	transform_min_element(Iterator Beg, Iterator End, Transform Fn){
		auto Min = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::max();
		Iterator MinItr = End;

		for(; Beg != End; ++Beg){
			auto Val = Fn(*Beg);
			if(Val < Min){
				Min = Val;
				MinItr = Beg;
			}
		}
		return std::make_pair(Min,MinItr);
	}
	template<typename Iterator, typename Transform>
	std::pair<std::pair<decltype(std::declval<Transform>()(*std::declval<Iterator>())), Iterator>,std::pair<decltype(std::declval<Transform>()(*std::declval<Iterator>())), Iterator>>
	transform_minmax_element(Iterator Beg, Iterator End, Transform Fn){
		auto Min = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::max();
		Iterator MinItr = End;
		auto Max = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::lowest();
		Iterator MaxItr = End;

		for(; Beg != End; ++Beg) {
			auto Val = Fn(*Beg);
			if(Val < Min){
				Min = Val;
				MinItr = Beg;
			}
			if(Val > Max){
				Max = Val;
				MaxItr = Beg;
			}
		}
		return std::make_pair(std::make_pair(Min,MinItr), std::make_pair(Max,MaxItr));
	}
	template<typename Iterator, typename Compare>
	std::pair<Iterator, Iterator> widest_equal_range(Iterator Beg, Iterator End, Compare&& Comp){
		auto Pair = std::make_pair(Beg, Beg);
		auto BPair = std::make_pair(End, End);
		unsigned int BDis = 0;

		while(Pair.second != End){
			Pair.first = Pair.second;
			Pair.second = std::upper_bound(Pair.first, End, *(Pair.first), Comp);
			unsigned int Dis = std::distance(Pair.first, Pair.second);

			if(BDis < Dis){
				BDis = Dis;
				BPair = Pair;
			}
		}

		return BPair;
	}
	template<typename Iterator>
	std::pair<Iterator, Iterator> widest_equal_range(Iterator Beg, Iterator End){
		auto Pair = std::make_pair(Beg, Beg);
		auto BPair = std::make_pair(End, End);
		unsigned int BDis = 0;

		while(Pair.second != End){
			Pair.first = Pair.second;
			Pair.second = std::upper_bound(Pair.first, End, *(Pair.first));
			unsigned int Dis = std::distance(Pair.first, Pair.second);

			if(BDis < Dis){
				BDis = Dis;
				BPair = Pair;
			}
		}

		return BPair;
	}

	template<typename T, typename output_iterator, typename internal_cast_type = double>
	output_iterator generate_range(T lower, T upper, unsigned int n, output_iterator out) {
		for(unsigned int i = 0; i < n; ++i) {
			*(out++) = static_cast<internal_cast_type>(lower*(n - 1 - i) + upper *i) / (n - 1);
		}
		return out;
	}
}
#
#endif
<commit_msg>Fix: transform_max_element sometimes use reference for the return value.<commit_after>#ifndef HMLIB_ALGORITHM_ALGORITHM_INC
#define HMLIB_ALGORITHM_ALGORITHM_INC 100
#
#include<utility>
#include<algorithm>
namespace hmLib{
	/*! @brief Remove elements from the given range with allowing change order of elements (value version).
	This is altenative faster algorithm of std::remove, but after applying this function the elements order can be changed.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Value The removing value from the range
	@return End of non-removed elemetns */
	template<typename bidirectional_iterator, typename type>
	bidirectional_iterator unstable_remove(bidirectional_iterator Beg, bidirectional_iterator End, const type& Value) {
		while(Beg!=End) {
			if(*Beg==Value) {
				--End;
				while(Beg!=End) {
					if(*End!=Value) {
						*Beg = std::move(*End);
						++Beg;
						break;
					} else {
						--End;
					}
				}
			} else {
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range with allowing change order of elements (functor version).
	This is altenative faster algorithm of std::remove_if, but after applying this function the elements order can be changed.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Cond All elemtns are evaluated as Cond(*Beg). If true is returned, the element is removed from the range.
	@return End of non-removed elemetns */
	template<typename bidirectional_iterator, typename condition>
	bidirectional_iterator unstable_remove_if(bidirectional_iterator Beg, bidirectional_iterator End, condition Cond) {
		while(Beg!=End) {
			if(Cond(*Beg)) {
				--End;
				while(Beg!=End) {
					if(!Cond(*End)) {
						*Beg = std::move(*End);
						++Beg;
						break;
					} else {
						--End;
					}
				}
			} else {
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range by using swap function instead of move (value version).
	This is altenative algorithm of std::remove, but use std::swap for moving elements.
	This means that the removed elements can be still accessible.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Value The removing value from the range
	@return End of non-removed elemetns */
	template<typename forward_iterator, typename type>
	forward_iterator swap_remove(forward_iterator Beg, forward_iterator End, const type& Value) {
		for(auto Itr = Beg; Itr!=End; ++Itr) {
			if(*Itr!=Value) {
				if(Beg!=Itr)std::swap(*Beg, *Itr);
				++Beg;
			}
		}
		return Beg;
	}
	/*! @brief Remove elements from the given range by using swap function instead of move (functor version).
	This is altenative algorithm of std::remove_if, but use std::swap for moving elements.
	This means that the removed elements can be still accessible.
	@param [in] Beg Begin iterator of the range
	@param [in] End End iterator of the range
	@param [in] Cond All elemtns are evaluated as Cond(*Beg). If true is returned, the element is removed from the range.
	@return End of non-removed elemetns */
	template<typename forward_iterator, typename condition>
	forward_iterator swap_remove_if(forward_iterator Beg, forward_iterator End, condition Cond) {
		//Itr: condition checked element
		//Beg: end of remaining elements

		auto Itr = Beg;
		//Beg==Itr as long as Cond is false
		while(Itr!=End) {
			if(Cond(*Itr)){
				++Itr;
				break;
			}
			++Beg;
			++Itr;
		}
		//Beg!=Itr
		while(Itr!=End){
			if(!Cond(*Itr)){
				std::swap(*Beg, *Itr);
				++Beg;
			}
			++Itr;
		}
		return Beg;
	}

	template<typename Iterator, typename Transform>
	auto transform_max_element(Iterator Beg, Iterator End, Transform Fn){
		auto Max = std::numeric_limits<typename std::remove_reference<decltype(Fn(*Beg))>::type>::lowest();
		Iterator MaxItr = End;

		for(; Beg != End; ++Beg){
			auto Val = Fn(*Beg);
			if(Val > Max){
				Max = Val;
				MaxItr = Beg;
			}
		}
		return std::make_pair(Max,MaxItr);
	}
	template<typename Iterator, typename Transform>
	auto transform_min_element(Iterator Beg, Iterator End, Transform Fn){
		auto Min = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::max();
		Iterator MinItr = End;

		for(; Beg != End; ++Beg){
			auto Val = Fn(*Beg);
			if(Val < Min){
				Min = Val;
				MinItr = Beg;
			}
		}
		return std::make_pair(Min,MinItr);
	}
	template<typename Iterator, typename Transform>
	auto transform_minmax_element(Iterator Beg, Iterator End, Transform Fn){
		auto Min = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::max();
		Iterator MinItr = End;
		auto Max = std::numeric_limits<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::lowest();
		Iterator MaxItr = End;

		for(; Beg != End; ++Beg) {
			auto Val = Fn(*Beg);
			if(Val < Min){
				Min = Val;
				MinItr = Beg;
			}
			if(Val > Max){
				Max = Val;
				MaxItr = Beg;
			}
		}
		return std::make_pair(std::make_pair(Min,MinItr), std::make_pair(Max,MaxItr));
	}
	template<typename Iterator, typename Compare>
	std::pair<Iterator, Iterator> widest_equal_range(Iterator Beg, Iterator End, Compare&& Comp){
		auto Pair = std::make_pair(Beg, Beg);
		auto BPair = std::make_pair(End, End);
		unsigned int BDis = 0;

		while(Pair.second != End){
			Pair.first = Pair.second;
			Pair.second = std::upper_bound(Pair.first, End, *(Pair.first), Comp);
			unsigned int Dis = std::distance(Pair.first, Pair.second);

			if(BDis < Dis){
				BDis = Dis;
				BPair = Pair;
			}
		}

		return BPair;
	}
	template<typename Iterator>
	std::pair<Iterator, Iterator> widest_equal_range(Iterator Beg, Iterator End){
		auto Pair = std::make_pair(Beg, Beg);
		auto BPair = std::make_pair(End, End);
		unsigned int BDis = 0;

		while(Pair.second != End){
			Pair.first = Pair.second;
			Pair.second = std::upper_bound(Pair.first, End, *(Pair.first));
			unsigned int Dis = std::distance(Pair.first, Pair.second);

			if(BDis < Dis){
				BDis = Dis;
				BPair = Pair;
			}
		}

		return BPair;
	}

	template<typename T, typename output_iterator, typename internal_cast_type = double>
	output_iterator generate_range(T lower, T upper, unsigned int n, output_iterator out) {
		for(unsigned int i = 0; i < n; ++i) {
			*(out++) = static_cast<internal_cast_type>(lower*(n - 1 - i) + upper *i) / (n - 1);
		}
		return out;
	}
}
#
#endif
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageAdaptor.h"
#include "itkAffineTransform.h"
#include "itkArray.h"
#include "itkAsinImageAdaptor.h"
#include "itkAtanImageAdaptor.h"
#include "itkBackwardDifferenceOperator.h"
#include "itkBloxBoundaryPointImage.h"
#include "itkBloxBoundaryPointItem.h"
#include "itkBloxBoundaryPointPixel.h"
#include "itkBloxCoreAtomImage.h"
#include "itkBloxCoreAtomItem.h"
#include "itkBloxCoreAtomPixel.h"
#include "itkBloxImage.h"
#include "itkBloxItem.h"
#include "itkBloxPixel.h"
#include "itkBluePixelAccessor.h"
#include "itkBoundingBox.h"
#include "itkByteSwapper.h"
#include "itkCellBoundary.h"
#include "itkCellInterface.h"
#include "itkCellInterfaceVisitor.h"
#include "itkCentralDifferenceImageFunction.h"
#include "itkColorTable.h"
#include "itkCommand.h"
#include "itkConditionalIterator.h"
#include "itkConicShellInteriorExteriorSpatialFunction.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkConstRandomAccessNeighborhoodIterator.h"
#include "itkConstSliceIterator.h"
#include "itkConstSmartNeighborhoodIterator.h"
#include "itkConstantBoundaryCondition.h"
#include "itkContinuousIndex.h"
#include "itkCosImageAdaptor.h"
#include "itkCovariantVector.h"
#include "itkCreateObjectFunction.h"
#include "itkDataObject.h"
#include "itkDefaultDynamicMeshTraits.h"
#include "itkDefaultImageTraits.h"
#include "itkDefaultPixelAccessor.h"
#include "itkDefaultStaticMeshTraits.h"
#include "itkDenseFiniteDifferenceImageFilter.h"
#include "itkDerivativeOperator.h"
#include "itkDirectory.h"
#include "itkDynamicLoader.h"
#include "itkElasticBodySplineKernelTransform.h"
#include "itkEllipsoidInteriorExteriorSpatialFunction.h"
#include "itkEntropyPreservingGradientMagnitudeImageFunction.h"
#include "itkExceptionObject.h"
#include "itkExpImageAdaptor.h"
#include "itkFastMutexLock.h"
#include "itkFileOutputWindow.h"
#include "itkFiniteDifferenceEquation.h"
#include "itkFiniteDifferenceImageFilter.h"
#include "itkFloodFilledSpatialFunctionConditionalIterator.h"
#include "itkForwardDifferenceOperator.h"
#include "itkFunctionBase.h"
#include "itkGaussianOperator.h"
#include "itkGreenPixelAccessor.h"
#include "itkHexahedronCell.h"
#include "itkImage.h"
#include "itkImageAdaptor.h"
#include "itkImageBase.h"
#include "itkImageBoundaryCondition.h"
#include "itkImageConstIterator.h"
#include "itkImageConstIteratorWithIndex.h"
#include "itkImageContainerInterface.h"
#include "itkImageFunction.h"
#include "itkImageIO.h"
#include "itkImageIOBase.h"
#include "itkImageIOCommon.h"
#include "itkImageIterator.h"
#include "itkImageIteratorWithIndex.h"
#include "itkImageLinearConstIteratorWithIndex.h"
#include "itkImageLinearIteratorWithIndex.h"
#include "itkImageRegion.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImageRegionMultidimensionalSplitter.h"
#include "itkImageRegionReverseIterator.h"
#include "itkImageRegionSplitter.h"
#include "itkImageReverseIterator.h"
#include "itkImageSliceConstIteratorWithIndex.h"
#include "itkImageSliceIteratorWithIndex.h"
#include "itkImageSource.h"
#include "itkImageToImageFilter.h"
#include "itkImportImageContainer.h"
#include "itkIndent.h"
#include "itkIndex.h"
#include "itkIndexedContainerInterface.h"
#include "itkIntTypes.h"
#include "itkInteriorExteriorSpatialFunction.h"
#include "itkInterpolateImageFunction.h"
#include "itkKernelTransform.h"
#include "itkLevelSetCurvatureFunction.h"
#include "itkLightObject.h"
#include "itkLightProcessObject.h"
#include "itkLineCell.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkLog10ImageAdaptor.h"
#include "itkLogImageAdaptor.h"
#include "itkMacro.h"
#include "itkMapContainer.h"
#include "itkMatrix.h"
#include "itkMesh.h"
#include "itkMeshRegion.h"
#include "itkMultiThreader.h"
#include "itkMutexLock.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include "itkNeighborhood.h"
#include "itkNeighborhoodAlgorithm.h"
#include "itkNeighborhoodAllocator.h"
#include "itkNeighborhoodInnerProduct.h"
#include "itkNeighborhoodIterator.h"
#include "itkNeighborhoodOperator.h"
#include "itkNthElementImageAdaptor.h"
#include "itkNthElementPixelAccessor.h"
#include "itkNumericTraits.h"
#include "itkObject.h"
#include "itkObjectFactory.h"
#include "itkObjectFactoryBase.h"
#include "itkOffset.h"
#include "itkOutputWindow.h"
#include "itkPixelAccessor.h"
#include "itkPixelTraits.h"
#include "itkPoint.h"
#include "itkPointLocator.h"
#include "itkPointSet.h"
#include "itkPolygonCell.h"
#include "itkProcessObject.h"
#include "itkQuadrilateralCell.h"
#include "itkQuaternionRigidTransform.h"
#include "itkRGBAPixel.h"
#include "itkRGBPixel.h"
#include "itkRandomAccessNeighborhoodIterator.h"
#include "itkRedPixelAccessor.h"
#include "itkRegion.h"
#include "itkRigid3DPerspectiveTransform.h"
#include "itkRigid3DTransform.h"
#include "itkScalarVector.h"
#include "itkScaleTransform.h"
#include "itkSimpleFastMutexLock.h"
#include "itkSimpleImageRegionConstIterator.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkSinImageAdaptor.h"
#include "itkSize.h"
#include "itkSliceIterator.h"
#include "itkSmartNeighborhoodIterator.h"
#include "itkSmartPointer.h"
#include "itkSmartPointerForwardReference.h"
#include "itkSpatialFunction.h"
#include "itkSphereSpatialFunction.h"
#include "itkSqrtImageAdaptor.h"
#include "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"
#include "itkTanImageAdaptor.h"
#include "itkTetrahedronCell.h"
#include "itkThinPlateSplineKernelTransform.h"
#include "itkTimeStamp.h"
#include "itkTransform.h"
#include "itkTranslationTransform.h"
#include "itkTriangleCell.h"
#include "itkUpwindDerivativeImageFunction.h"
#include "itkValarrayImageContainer.h"
#include "itkVector.h"
#include "itkVectorContainer.h"
#include "itkVectorInterpolateImageFunction.h"
#include "itkVectorLinearInterpolateImageFunction.h"
#include "itkVectorNeighborhoodInnerProduct.h"
#include "itkVersion.h"
#include "itkVersor.h"
#include "itkVersorRigid3DTransform.h"
#include "itkVertexCell.h"
#include "itkWeakPointer.h"
#include "itkXMLFileOutputWindow.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itk_alloc.h"
#include "itk_hash_map.h"
#include "itk_hash_set.h"
#include "itk_hashtable.h"
#include "vcl_alloc.h"

int main ( int argc, char* argv )
{

  return 0;
}

<commit_msg>ENH:Moved MeshSource and MeshToMeshFilter to Common/<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageAdaptor.h"
#include "itkAffineTransform.h"
#include "itkArray.h"
#include "itkAsinImageAdaptor.h"
#include "itkAtanImageAdaptor.h"
#include "itkBackwardDifferenceOperator.h"
#include "itkBloxBoundaryPointImage.h"
#include "itkBloxBoundaryPointItem.h"
#include "itkBloxBoundaryPointPixel.h"
#include "itkBloxCoreAtomImage.h"
#include "itkBloxCoreAtomItem.h"
#include "itkBloxCoreAtomPixel.h"
#include "itkBloxImage.h"
#include "itkBloxItem.h"
#include "itkBloxPixel.h"
#include "itkBluePixelAccessor.h"
#include "itkBoundingBox.h"
#include "itkByteSwapper.h"
#include "itkCellBoundary.h"
#include "itkCellInterface.h"
#include "itkCellInterfaceVisitor.h"
#include "itkCentralDifferenceImageFunction.h"
#include "itkColorTable.h"
#include "itkCommand.h"
#include "itkConditionalIterator.h"
#include "itkConicShellInteriorExteriorSpatialFunction.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkConstRandomAccessNeighborhoodIterator.h"
#include "itkConstSliceIterator.h"
#include "itkConstSmartNeighborhoodIterator.h"
#include "itkConstantBoundaryCondition.h"
#include "itkContinuousIndex.h"
#include "itkCosImageAdaptor.h"
#include "itkCovariantVector.h"
#include "itkCreateObjectFunction.h"
#include "itkDataObject.h"
#include "itkDefaultDynamicMeshTraits.h"
#include "itkDefaultImageTraits.h"
#include "itkDefaultPixelAccessor.h"
#include "itkDefaultStaticMeshTraits.h"
#include "itkDenseFiniteDifferenceImageFilter.h"
#include "itkDerivativeOperator.h"
#include "itkDirectory.h"
#include "itkDynamicLoader.h"
#include "itkElasticBodySplineKernelTransform.h"
#include "itkEllipsoidInteriorExteriorSpatialFunction.h"
#include "itkEntropyPreservingGradientMagnitudeImageFunction.h"
#include "itkExceptionObject.h"
#include "itkExpImageAdaptor.h"
#include "itkFastMutexLock.h"
#include "itkFileOutputWindow.h"
#include "itkFiniteDifferenceEquation.h"
#include "itkFiniteDifferenceImageFilter.h"
#include "itkFloodFilledSpatialFunctionConditionalIterator.h"
#include "itkForwardDifferenceOperator.h"
#include "itkFunctionBase.h"
#include "itkGaussianOperator.h"
#include "itkGreenPixelAccessor.h"
#include "itkHexahedronCell.h"
#include "itkImage.h"
#include "itkImageAdaptor.h"
#include "itkImageBase.h"
#include "itkImageBoundaryCondition.h"
#include "itkImageConstIterator.h"
#include "itkImageConstIteratorWithIndex.h"
#include "itkImageContainerInterface.h"
#include "itkImageFunction.h"
#include "itkImageIO.h"
#include "itkImageIOBase.h"
#include "itkImageIOCommon.h"
#include "itkImageIterator.h"
#include "itkImageIteratorWithIndex.h"
#include "itkImageLinearConstIteratorWithIndex.h"
#include "itkImageLinearIteratorWithIndex.h"
#include "itkImageRegion.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImageRegionMultidimensionalSplitter.h"
#include "itkImageRegionReverseIterator.h"
#include "itkImageRegionSplitter.h"
#include "itkImageReverseIterator.h"
#include "itkImageSliceConstIteratorWithIndex.h"
#include "itkImageSliceIteratorWithIndex.h"
#include "itkImageSource.h"
#include "itkImageToImageFilter.h"
#include "itkImportImageContainer.h"
#include "itkIndent.h"
#include "itkIndex.h"
#include "itkIndexedContainerInterface.h"
#include "itkIntTypes.h"
#include "itkInteriorExteriorSpatialFunction.h"
#include "itkInterpolateImageFunction.h"
#include "itkKernelTransform.h"
#include "itkLevelSetCurvatureFunction.h"
#include "itkLightObject.h"
#include "itkLightProcessObject.h"
#include "itkLineCell.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkLog10ImageAdaptor.h"
#include "itkLogImageAdaptor.h"
#include "itkMacro.h"
#include "itkMapContainer.h"
#include "itkMatrix.h"
#include "itkMesh.h"
#include "itkMeshRegion.h"
#include "itkMeshSource.h"
#include "itkMeshToMeshFilter.h"
#include "itkMultiThreader.h"
#include "itkMutexLock.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include "itkNeighborhood.h"
#include "itkNeighborhoodAlgorithm.h"
#include "itkNeighborhoodAllocator.h"
#include "itkNeighborhoodInnerProduct.h"
#include "itkNeighborhoodIterator.h"
#include "itkNeighborhoodOperator.h"
#include "itkNthElementImageAdaptor.h"
#include "itkNthElementPixelAccessor.h"
#include "itkNumericTraits.h"
#include "itkObject.h"
#include "itkObjectFactory.h"
#include "itkObjectFactoryBase.h"
#include "itkOffset.h"
#include "itkOutputWindow.h"
#include "itkPixelAccessor.h"
#include "itkPixelTraits.h"
#include "itkPoint.h"
#include "itkPointLocator.h"
#include "itkPointSet.h"
#include "itkPolygonCell.h"
#include "itkProcessObject.h"
#include "itkQuadrilateralCell.h"
#include "itkQuaternionRigidTransform.h"
#include "itkRGBAPixel.h"
#include "itkRGBPixel.h"
#include "itkRandomAccessNeighborhoodIterator.h"
#include "itkRedPixelAccessor.h"
#include "itkRegion.h"
#include "itkRigid3DPerspectiveTransform.h"
#include "itkRigid3DTransform.h"
#include "itkScalarVector.h"
#include "itkScaleTransform.h"
#include "itkSimpleFastMutexLock.h"
#include "itkSimpleImageRegionConstIterator.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkSinImageAdaptor.h"
#include "itkSize.h"
#include "itkSliceIterator.h"
#include "itkSmartNeighborhoodIterator.h"
#include "itkSmartPointer.h"
#include "itkSmartPointerForwardReference.h"
#include "itkSpatialFunction.h"
#include "itkSphereSpatialFunction.h"
#include "itkSqrtImageAdaptor.h"
#include "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"
#include "itkTanImageAdaptor.h"
#include "itkTetrahedronCell.h"
#include "itkThinPlateSplineKernelTransform.h"
#include "itkTimeStamp.h"
#include "itkTransform.h"
#include "itkTranslationTransform.h"
#include "itkTriangleCell.h"
#include "itkUpwindDerivativeImageFunction.h"
#include "itkValarrayImageContainer.h"
#include "itkVector.h"
#include "itkVectorContainer.h"
#include "itkVectorInterpolateImageFunction.h"
#include "itkVectorLinearInterpolateImageFunction.h"
#include "itkVectorNeighborhoodInnerProduct.h"
#include "itkVersion.h"
#include "itkVersor.h"
#include "itkVersorRigid3DTransform.h"
#include "itkVertexCell.h"
#include "itkWeakPointer.h"
#include "itkXMLFileOutputWindow.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itk_alloc.h"
#include "itk_hash_map.h"
#include "itk_hash_set.h"
#include "itk_hashtable.h"
#include "vcl_alloc.h"

int main ( int argc, char* argv )
{

  return 0;
}

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * 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 "caffe2/operators/text_file_reader_utils.h"

#include <fcntl.h>
#include <cstring>
#include <sstream>

namespace caffe2 {

Tokenizer::Tokenizer(const std::vector<char>& delims, char escape)
    : escape_(escape) {
  reset();
  std::memset(delimTable_, 0, sizeof(delimTable_));
  for (int i = 0; i < delims.size(); ++i) {
    delimTable_[(unsigned char)delims.at(i)] = i + 1;
  }
}

void Tokenizer::reset() {
  toBeSkipped_ = 0;
  startDelimId_ = 0;
  leftover_.clear();
}

void Tokenizer::next(char* start, char* end, TokenizedString& tokenized) {
  tokenized.modifiedStrings_.clear();
  tokenized.tokens_.clear();

  char* currentStart = start;
  std::string* copied = nullptr;
  if (!leftover_.empty()) {
    tokenized.modifiedStrings_.emplace_back(new std::string());
    copied = tokenized.modifiedStrings_.back().get();
    *copied = std::move(leftover_);
  }

  char* ch;
  for (ch = start + toBeSkipped_; ch < end; ++ch) {
    if (*ch == escape_) {
      if (!copied) {
        tokenized.modifiedStrings_.emplace_back(new std::string());
        copied = tokenized.modifiedStrings_.back().get();
      }
      copied->append(currentStart, ch);
      currentStart = ch + 1;
      // skip next character, since it's escaped
      ++ch;
      continue;
    }
    int newDelimId = delimTable_[(unsigned char)*ch];
    if (newDelimId > 0) {
      // found delimiter
      tokenized.tokens_.emplace_back();
      auto& token = tokenized.tokens_.back();
      token.startDelimId = startDelimId_;
      if (copied) {
        copied->append(currentStart, ch);
        const char* c_str = copied->data();
        token.start = c_str;
        token.end = c_str + copied->size();
      } else {
        token.start = currentStart;
        token.end = ch;
      }
      currentStart = ch + 1;
      copied = nullptr;
      startDelimId_ = newDelimId - 1;
    }
  }
  tokenized.lastDelim_ = startDelimId_;

  toBeSkipped_ = ch - end;
  if (copied) {
    copied->append(currentStart, end);
    leftover_ = std::move(*copied);
  } else {
    leftover_.assign(currentStart, end);
  }
}

FileReader::FileReader(const std::string& path, size_t bufferSize)
    : bufferSize_(bufferSize), buffer_(new char[bufferSize]) {
  fd_ = open(path.c_str(), O_RDONLY, 0777);
  if (fd_ < 0) {
    throw std::runtime_error(
        "Error opening file for reading: " + std::string(std::strerror(errno)) +
        " Path=" + path);
  }
}

void FileReader::reset() {
  if (lseek(fd_, 0, SEEK_SET) == -1) {
    throw std::runtime_error(
        "Error reseting file cursor: " + std::string(std::strerror(errno)));
  }
}

FileReader::~FileReader() {
  if (fd_ >= 0) {
    close(fd_);
  }
}

void FileReader::operator()(CharRange& range) {
  char* buffer = buffer_.get();
  auto numRead = read(fd_, buffer, bufferSize_);
  if (numRead == -1) {
    throw std::runtime_error(
        "Error reading file: " + std::string(std::strerror(errno)));
  }
  if (numRead == 0) {
    range.start = nullptr;
    range.end = nullptr;
    return;
  }
  range.start = buffer;
  range.end = buffer + numRead;
}
}
<commit_msg>Add missing cerrno include in text_file_reader_utils<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * 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 "caffe2/operators/text_file_reader_utils.h"

#include <fcntl.h>
#include <cerrno>
#include <cstring>
#include <sstream>

namespace caffe2 {

Tokenizer::Tokenizer(const std::vector<char>& delims, char escape)
    : escape_(escape) {
  reset();
  std::memset(delimTable_, 0, sizeof(delimTable_));
  for (int i = 0; i < delims.size(); ++i) {
    delimTable_[(unsigned char)delims.at(i)] = i + 1;
  }
}

void Tokenizer::reset() {
  toBeSkipped_ = 0;
  startDelimId_ = 0;
  leftover_.clear();
}

void Tokenizer::next(char* start, char* end, TokenizedString& tokenized) {
  tokenized.modifiedStrings_.clear();
  tokenized.tokens_.clear();

  char* currentStart = start;
  std::string* copied = nullptr;
  if (!leftover_.empty()) {
    tokenized.modifiedStrings_.emplace_back(new std::string());
    copied = tokenized.modifiedStrings_.back().get();
    *copied = std::move(leftover_);
  }

  char* ch;
  for (ch = start + toBeSkipped_; ch < end; ++ch) {
    if (*ch == escape_) {
      if (!copied) {
        tokenized.modifiedStrings_.emplace_back(new std::string());
        copied = tokenized.modifiedStrings_.back().get();
      }
      copied->append(currentStart, ch);
      currentStart = ch + 1;
      // skip next character, since it's escaped
      ++ch;
      continue;
    }
    int newDelimId = delimTable_[(unsigned char)*ch];
    if (newDelimId > 0) {
      // found delimiter
      tokenized.tokens_.emplace_back();
      auto& token = tokenized.tokens_.back();
      token.startDelimId = startDelimId_;
      if (copied) {
        copied->append(currentStart, ch);
        const char* c_str = copied->data();
        token.start = c_str;
        token.end = c_str + copied->size();
      } else {
        token.start = currentStart;
        token.end = ch;
      }
      currentStart = ch + 1;
      copied = nullptr;
      startDelimId_ = newDelimId - 1;
    }
  }
  tokenized.lastDelim_ = startDelimId_;

  toBeSkipped_ = ch - end;
  if (copied) {
    copied->append(currentStart, end);
    leftover_ = std::move(*copied);
  } else {
    leftover_.assign(currentStart, end);
  }
}

FileReader::FileReader(const std::string& path, size_t bufferSize)
    : bufferSize_(bufferSize), buffer_(new char[bufferSize]) {
  fd_ = open(path.c_str(), O_RDONLY, 0777);
  if (fd_ < 0) {
    throw std::runtime_error(
        "Error opening file for reading: " + std::string(std::strerror(errno)) +
        " Path=" + path);
  }
}

void FileReader::reset() {
  if (lseek(fd_, 0, SEEK_SET) == -1) {
    throw std::runtime_error(
        "Error reseting file cursor: " + std::string(std::strerror(errno)));
  }
}

FileReader::~FileReader() {
  if (fd_ >= 0) {
    close(fd_);
  }
}

void FileReader::operator()(CharRange& range) {
  char* buffer = buffer_.get();
  auto numRead = read(fd_, buffer, bufferSize_);
  if (numRead == -1) {
    throw std::runtime_error(
        "Error reading file: " + std::string(std::strerror(errno)));
  }
  if (numRead == 0) {
    range.start = nullptr;
    range.end = nullptr;
    return;
  }
  range.start = buffer;
  range.end = buffer + numRead;
}
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkSmartPointerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
#include "itkSmartPointer.h"

class itkTestObject
{
public:
  typedef itkSmartPointer<itkTestObject> Pointer;
  static itkTestObject::Pointer New();
  void Register()
    {
    std::cout << "Register " << *this << " count:"
              << (m_ReferenceCount+1) << "  " << std::endl;
    m_ReferenceCount++;
    }
  void UnRegister()
    {
    std::cout << "UnRegister " << this << " count:"
              << (m_ReferenceCount-1) << "  " << std::endl;

    m_ReferenceCount--;
    if ( m_ReferenceCount == 0 )
      {
      delete this;
      }
    }
    inline friend std::ostream &operator << (std::ostream &os,
                                             itkTestObject const& o)
    {
      os << "itkTestObject " << (void*)&o << " " << o.m_ReferenceCount;
      return os;
    }

  std::ostream& Print(std::ostream& os) const
    {
    os << "itkTestObject " << (void*)this << " " << this->m_ReferenceCount;
    return os;
    }

protected:
  itkTestObject()
    {
    m_ReferenceCount = 0;
    std::cout << "construct itkTestObject " << *this << std::endl;
    }
  ~itkTestObject()
    {
    std::cout << "destruct itkTestObject " << *this << std::endl;
    }

private:
  unsigned int m_ReferenceCount;
};

itkTestObject::Pointer itkTestObject::New()
{
  return itkTestObject::Pointer(new itkTestObject);
}

int main()
{
  std::cout <<"second test" << std::endl;
  {
  itkTestObject::Pointer o1 = itkTestObject::New();
  std::cout << "o1 " << &o1 << std::endl;
  itkTestObject::Pointer o2 = itkTestObject::New();
  std::cout << "o2 " << &o2 << std::endl;
  itkTestObject::Pointer o3 = itkTestObject::New();
  std::cout << "o3 " << &o3 << std::endl;
  itkTestObject::Pointer o4 = itkTestObject::New();
  std::cout << "o4 " << &o4 << std::endl;

  o1 = o2;
  o2 = o3;
  o4 = o1;
  if ( o1 < o2 )
    {
    std::cout << "o1 is < o2 " << o1 << " " << o2 << std::endl;
    }
  else
    {
    std::cout << "o1 is not < o2 " << &o1 << " " << &o2 << std::endl;
    }
  }
  std::cout <<"end second test" << std::endl << std::endl;

  std::cout <<"first test" << std::endl;
  {
  itkTestObject::Pointer o1 = itkTestObject::New();
  }
  std::cout <<"end first test" << std::endl << std::endl;
  return 0;
}

<commit_msg>ENH: add a test for polymorphic use of smart pointers<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkSmartPointerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
#include "itkSmartPointer.h"

class itkTestObject
{
public:
  typedef itkSmartPointer<itkTestObject> Pointer;
  static itkTestObject::Pointer New();
  virtual void Register()
    {
    std::cout << "Register " << *this << " count:"
              << (m_ReferenceCount+1) << "  " << std::endl;
    m_ReferenceCount++;
    }
  virtual void UnRegister()
    {
    std::cout << "UnRegister " << this << " count:"
              << (m_ReferenceCount-1) << "  " << std::endl;

    m_ReferenceCount--;
    if ( m_ReferenceCount == 0 )
      {
      delete this;
      }
    }
    inline friend std::ostream &operator << (std::ostream &os,
                                             itkTestObject const& o)
    {
      os << "itkTestObject " << (void*)&o << " " << o.m_ReferenceCount;
      return os;
    }

  std::ostream& Print(std::ostream& os) const
    {
    os << "itkTestObject " << (void*)this << " " << this->m_ReferenceCount;
    return os;
    }

protected:
  itkTestObject()
    {
    m_ReferenceCount = 0;
    std::cout << "construct itkTestObject " << *this << std::endl;
    }
  ~itkTestObject()
    {
    std::cout << "destruct itkTestObject " << *this << std::endl;
    }

private:
  unsigned int m_ReferenceCount;
};

itkTestObject::Pointer itkTestObject::New()
{
  return itkTestObject::Pointer(new itkTestObject);
}

class itkTestObjectSubClass : public itkTestObject
{
public:
  typedef itkSmartPointer<itkTestObjectSubClass> Pointer;
  static itkTestObjectSubClass::Pointer New();
};

itkTestObjectSubClass::Pointer itkTestObjectSubClass::New()
{
  return itkTestObjectSubClass::Pointer(new itkTestObjectSubClass);
}

int main()
{
  itkTestObject::Pointer to = itkTestObjectSubClass::New();
  itkTestObjectSubClass::Pointer sc = dynamic_cast<itkTestObjectSubClass*>((itkTestObject*)to);

  std::cout <<"second test" << std::endl;
  {
  itkTestObject::Pointer o1 = itkTestObject::New();
  std::cout << "o1 " << &o1 << std::endl;
  itkTestObject::Pointer o2 = itkTestObject::New();
  std::cout << "o2 " << &o2 << std::endl;
  itkTestObject::Pointer o3 = itkTestObject::New();
  std::cout << "o3 " << &o3 << std::endl;
  itkTestObject::Pointer o4 = itkTestObject::New();
  std::cout << "o4 " << &o4 << std::endl;

  o1 = o2;
  o2 = o3;
  o4 = o1;
  if ( o1 < o2 )
    {
    std::cout << "o1 is < o2 " << o1 << " " << o2 << std::endl;
    }
  else
    {
    std::cout << "o1 is not < o2 " << &o1 << " " << &o2 << std::endl;
    }
  }
  std::cout <<"end second test" << std::endl << std::endl;

  std::cout <<"first test" << std::endl;
  {
  itkTestObject::Pointer o1 = itkTestObject::New();
  }
  std::cout <<"end first test" << std::endl << std::endl;
  return 0;
}

<|endoftext|>


<commit_before>#include<chrono>
#include<iostream>
#include<mutex>
#include<random>
#include"../header/CThreadPool_Ret.h"

namespace
{
	std::mutex mut;

	size_t get()
	{
		using namespace std;
		static mt19937 mu{static_cast<mt19937::result_type>(chrono::high_resolution_clock::now().time_since_epoch().count())};
		return mu()%4;
	}
}

int main()
{
	using namespace std;
	nThread::CThreadPool_Ret<size_t> tp{4};	//merely size_t, not size_t()
	for(size_t i{0};i!=tp.count();++i)
		tp.add([&,i]{
			using namespace std;
			const auto sec{get()};
			this_thread::sleep_for(chrono::seconds{sec});
			lock_guard<mutex> lock{mut};
			cout<<"thread "<<i<<" wait "<<sec<<" sec"<<endl;
			return i;
		;});
	tp.wait(0);	//tp will block here until thread[0] complete
	cout<<tp.get(0)<<" complete"<<endl;	//get the return value from lambda
	//tp.get(0);	//do not call same id twice

	if(tp.valid(1))	//it means thread[1] has a function, and thread[1] is running
		cout<<tp.get(1)<<" complete"<<endl;	//tp will block here until thread[1] complete and return value from lambda
	if(tp.valid(1))	//this will return false, because you call tp.get(1)
		cout<<"hi, something must wrong"<<endl;

	//you don't need to call every get to guarantee all threads are not valid
	//the destructor of CThreadPool_Ret will deal with this
}<commit_msg>replace std::size_t with std::thread::id<commit_after>#include<chrono>
#include<iostream>
#include<mutex>
#include<queue>
#include<random>
#include<thread>
#include"../header/CThreadPool_Ret.h"

namespace
{
	std::mutex mut;

	size_t get()
	{
		using namespace std;
		static mt19937 mu{static_cast<mt19937::result_type>(chrono::high_resolution_clock::now().time_since_epoch().count())};
		return mu()%4;
	}
}

int main()
{
	using namespace std;
	nThread::CThreadPool_Ret<size_t> tp{4};	//merely size_t, not size_t()
	queue<nThread::CThreadPool_Ret<size_t>::thread_id> que;
	for(size_t i{0};i!=tp.count();++i)
		que.emplace(tp.add([&,i]{
			using namespace std;
			const auto sec{get()};
			this_thread::sleep_for(chrono::seconds{sec});
			lock_guard<mutex> lock{mut};
			cout<<"thread "<<i<<" wait "<<sec<<" sec"<<endl;
			return i;
		;}));
	tp.wait(que.front());	//tp will block here until thread[que.front()] complete
	cout<<tp.get(que.front())<<" complete"<<endl;	//get the return value from lambda
	//tp.get(que.front());	//do not call same id twice
	que.pop();

	if(tp.valid(que.front()))	//it means thread[que.front()] has a function, and thread[que.front()] is running
		cout<<tp.get(que.front())<<" complete"<<endl;	//tp will block here until thread[que.front()] complete and return value from lambda
	if(tp.valid(que.front()))	//this will return false, because you call tp.get(que.front())
		cout<<"hi, something must wrong"<<endl;

	//you don't need to call every get to guarantee all threads are not valid
	//the destructor of CThreadPool_Ret will deal with this
}<|endoftext|>