add examble: perseptron/g3.cpp brainfuck/x86_compile.cpp

This commit is contained in:
bolero-MURAKAMI 2014-12-27 13:56:41 +09:00
parent 5ccbc4e903
commit 03b4eda323
15 changed files with 1411 additions and 8 deletions

View file

@ -0,0 +1,45 @@
// 99 Bottles of Beer
">+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>"
"[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<"
"-]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<"
"[>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++"
"+++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-"
"]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+"
"++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>"
">>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++"
"+>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------"
"---->-]<.>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++"
"++[<---------->-]<--.>+++++++++[<+++++++++>-]<--.-.>++++++++"
"[<---------->-]<++.>++++++++[<++++++++++>-]<++++.-----------"
"-.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-."
">++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<"
"-----.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>+++"
"+[<++++++>-]<--.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<."
"><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++"
"++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<++"
"+++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++"
"+++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]<"
"-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++."
"------.>+++++++[<---------->-]<+.>++++++++[<++++++++++>-]<-."
"-.---------.>+++++++[<---------->-]<+.>+++++++[<++++++++++>-"
"]<--.+++++++++++.++++++++.---------.>++++++++[<---------->-]"
"<++.>+++++[<+++++++++++++>-]<.+++++++++++++.----------.>++++"
"+++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<----->"
"-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<"
"++++++++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++"
".>+++++[<+++++++++++++>-]<.>+++[<++++++>-]<-.---.++++++.----"
"---.----------.>++++++++[<----------->-]<+.---.[-]<<<->[-]>["
"-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]"
">[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-]>>+>[<[-]<"
"<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<"
"<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+"
"<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>"
"-]<.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..---"
"-----.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++"
".>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<-"
"-.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-]"
"<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++["
"<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++"
"++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+."
">++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++"
"..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]"

View file

@ -0,0 +1,2 @@
// echo
"+[>,.<]"

View file

@ -0,0 +1,6 @@
// FizzBuzz
"++++++++++++[->++++++>+++++++++>+++++>++++++++++>++++++++++>+++>>>>>>++++++++<<<<<<<<<<<<]>-->--->++"
"++++>--->++>---->>>>+++>+++++>++++[>>>+[-<<[->>+>+<<<]>>>[-<<<+>>>]+<[[-]>-<<[->+>+<<]>>[-<<+>>]+<[["
"-]>-<<<+>->]>[-<<<--------->+++++++++>>>>>+<<<]<]>[-<+++++++[<<+++++++>>-]<++++++++>>]>>>]<<<<<<[<<<"
"<]>-[-<<+>+>]<[->+<]+<[[-]>-<]>[->+++<<<<<<<<<.>.>>>..>>+>>]>>-[-<<<+>+>>]<<[->>+<<]+<[[-]>-<]>[->>+"
"++++<<<<<<<<.>.>..>>+>>]<+<[[-]>-<]>[->>>>>[>>>>]<<<<[.<<<<]<]<<.>>>>>>-]"

View file

@ -0,0 +1,3 @@
// Hello, world!
"+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-."
"------------.<++++++++.--------.+++.------.--------.>+."

View file

@ -0,0 +1,11 @@
// Quine
"-"
">++>+++>+>+>+++>>>>>>>>>>>>>>>>>>>>>>+>+>++>+++>++>>+++"
">+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>>+++>>>>+++>>>+++"
">+>>>>>>>++>+++>+++>+>>+++>+++>+>+++>+>+++>+>++>+++>>>+"
">+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++"
">+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++"
">+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>"
"+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]"
">>>[>]+++>+"
"[+[<++++++++++++++++>-]<++++++++++.<]"

View file

@ -0,0 +1,2 @@
// Self-describing
"+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]"

View file

@ -0,0 +1,578 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <iostream>
#include <fstream>
#include <sprout/config.hpp>
#include <sprout/endian_traits.hpp>
#include <sprout/string.hpp>
#include <sprout/array.hpp>
#include <sprout/sub_array.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/range/algorithm.hpp>
#include <sprout/preprocessor/stringize.hpp>
#include <sprout/assert.hpp>
//
// PE関連の構造体
// <windows.h> からコピペ
//
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
//
// File header format.
//
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
//
// Directory format.
//
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
//
// Optional header format.
//
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
//
// Section header format.
//
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
// union {
// DWORD PhysicalAddress;
// DWORD VirtualSize;
// } Misc;
struct {
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
//
// 出力バイナリサイズ
//
#ifndef BRAINFUCK_BINARY_SIZE
# define BRAINFUCK_BINARY_SIZE (16 * 1024)
#endif
//
// ループ制限
//
#ifndef BRAINFUCK_LOOP_LIMIT
# define BRAINFUCK_LOOP_LIMIT 256
#endif
//
// 入力ファイル名
//
#ifndef BRAINFUCK_SOURCE_FILE
# define BRAINFUCK_SOURCE_FILE a.bf
#endif
//
// 定数
//
SPROUT_STATIC_CONSTEXPR std::size_t bin_size = BRAINFUCK_BINARY_SIZE;
SPROUT_STATIC_CONSTEXPR std::size_t loop_limit = BRAINFUCK_LOOP_LIMIT;
SPROUT_STATIC_CONSTEXPR auto source = sprout::to_string(
# include SPROUT_PP_STRINGIZE(BRAINFUCK_SOURCE_FILE)
);
SPROUT_STATIC_CONSTEXPR std::int32_t addr_putchar = 0x00405044;
SPROUT_STATIC_CONSTEXPR std::int32_t addr_getchar = addr_putchar + 4;
SPROUT_STATIC_CONSTEXPR std::int32_t addr_buf = 0x00406000;
//
// 出力用関数
//
template<typename OutputIterator, typename T>
SPROUT_CXX14_CONSTEXPR std::size_t
write_bytes(OutputIterator& out, T const& val) {
typedef sprout::little_endian_traits<T> traits;
for (std::size_t i = 0; i != traits::size(); ++i) {
*out++ = sprout::little_endian_traits<T>::get_byte(val, i);
}
return traits::size();
}
template<typename OutputIterator, typename T, std::size_t N>
SPROUT_CXX14_CONSTEXPR std::size_t
write_bytes(OutputIterator& out, T const(& vals)[N]) {
typedef sprout::little_endian_traits<T> traits;
for (std::size_t i = 0; i != N; ++i) {
::write_bytes(out, vals[i]);
}
return traits::size() * N;
}
template<typename OutputIterator, typename Head, typename... Tail>
SPROUT_CXX14_CONSTEXPR std::size_t
write_bytes(OutputIterator& out, Head const& head, Tail const&... tail) {
return ::write_bytes(out, head) + ::write_bytes(out, tail...);
}
template<typename OutputIterator>
SPROUT_CXX14_CONSTEXPR std::size_t
write_pe_header(OutputIterator& out, std::size_t n = 0) {
SPROUT_CONSTEXPR unsigned char stub[] = {
// 00-3b: DOS Header
'M', 'Z', 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 3c-3f: Pointer to PE Header (=80)
0x80, 0x00, 0x00, 0x00,
// 40-7f: DOS Stub
0xba, 0x10, 0x00, 0x0e, 0x1f, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x90, 0x90,
'T', 'h', 'i', 's', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'c', 'a', 'n',
'n', 'o', 't', ' ', 'b', 'e', ' ', 'r', 'u', 'n', ' ', 'i', 'n', ' ', 'D', 'O',
'S', ' ', 'm', 'o', 'd', 'e', '.', '\r', '\n', '$', 0, 0, 0, 0, 0, 0,
// 80-83: PE Signature
'P', 'E', 0, 0
};
n += ::write_bytes(
out,
stub
);
SPROUT_CONSTEXPR ::IMAGE_FILE_HEADER coff = {
0x014c, // Machine
3, // NumberOfSections
0, // TimeDateStamp
0, // PointerToSymbolTable
0, // NumberOfSymbols
sizeof(::IMAGE_OPTIONAL_HEADER32), // SizeOfOptionalHeader
0x030f // Characteristics
};
n += ::write_bytes(
out,
coff.Machine,
coff.NumberOfSections,
coff.TimeDateStamp,
coff.PointerToSymbolTable,
coff.NumberOfSymbols,
coff.SizeOfOptionalHeader,
coff.Characteristics
);
SPROUT_CONSTEXPR ::IMAGE_OPTIONAL_HEADER32 opt = {
0x010b, // Magic
6, 0, // MajorLinkerVersion, MinorLinkerVersion
::bin_size, // SizeOfCode
0, // SizeOfInitializedData
65536, // SizeOfUninitializedData
0x1000, // AddressOfEntryPoint
0x1000, // BaseOfCode
0x6000, // BaseOfData
0x00400000, // ImageBase
0x1000, // SectionAlignment
0x0200, // FileAlignment
4, 0, // MajorOperatingSystemVersion, MinorOperatingSystemVersion
0, 0, // MajorImageVersion, MinorImageVersion
4, 0, // MajorSubsystemVersion, MinorSubsystemVersion
0, // Win32VersionValue
0x16000, // SizeOfImage
0x200, // SizeOfHeaders
0, // CheckSum
3, // Subsystem
0, // DllCharacteristics
1024 * 1024, // SizeOfStackReserve
8 * 1024, // SizeOfStackCommit
1024 * 1024, // SizeOfHeapReserve
4 * 1024, // SizeOfHeapCommit
0, // LoaderFlags
16, // NumberOfRvaAndSizes
{
{},
{
0x5000, // VirtualAddress (import table)
100 // Size
},
{}
}
};
n += ::write_bytes(
out,
opt.Magic,
opt.MajorLinkerVersion, opt.MinorLinkerVersion,
opt.SizeOfCode,
opt.SizeOfInitializedData,
opt.SizeOfUninitializedData,
opt.AddressOfEntryPoint,
opt.BaseOfCode,
opt.BaseOfData,
opt.ImageBase,
opt.SectionAlignment,
opt.FileAlignment,
opt.MajorOperatingSystemVersion, opt.MinorOperatingSystemVersion,
opt.MajorImageVersion, opt.MinorImageVersion,
opt.MajorSubsystemVersion, opt.MinorSubsystemVersion,
opt.Win32VersionValue,
opt.SizeOfImage,
opt.SizeOfHeaders,
opt.CheckSum,
opt.Subsystem,
opt.DllCharacteristics,
opt.SizeOfStackReserve,
opt.SizeOfStackCommit,
opt.SizeOfHeapReserve,
opt.SizeOfHeapCommit,
opt.LoaderFlags,
opt.NumberOfRvaAndSizes,
opt.DataDirectory[0].VirtualAddress, opt.DataDirectory[0].Size,
opt.DataDirectory[1].VirtualAddress, opt.DataDirectory[1].Size
);
for (std::size_t i = 2; i != IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i) {
n += ::write_bytes(
out,
opt.DataDirectory[i].VirtualAddress, opt.DataDirectory[i].Size
);
}
SPROUT_CONSTEXPR ::IMAGE_SECTION_HEADER sects[3] = {
{
".text", // Name
{::bin_size}, // Misc.VirtualSize
0x1000, // VirtualAddress
::bin_size, // SizeOfRawData
0x400, // PointerToRawData
0, // PointerToRelocations
0, // PointerToLinenumbers
0, // NumberOfRelocations
0, // NumberOfLinenumbers
0x60500060 // Characteristics
},
{
".idata", // Name
{100}, // Misc.VirtualSize
0x5000, // VirtualAddress
512, // SizeOfRawData
0x200, // PointerToRawData
0, // PointerToRelocations
0, // PointerToLinenumbers
0, // NumberOfRelocations
0, // NumberOfLinenumbers
0xc0300040 // Characteristics
},
{
".bss", // Name
{65536}, // Misc.VirtualSize
0x6000, // VirtualAddress
0, // SizeOfRawData
0, // PointerToRawData
0, // PointerToRelocations
0, // PointerToLinenumbers
0, // NumberOfRelocations
0, // NumberOfLinenumbers
0xc0400080 // Characteristics
}
};
for (std::size_t i = 0; i != 3; ++i) {
n += ::write_bytes(
out,
sects[i].Name,
sects[i].Misc.VirtualSize,
sects[i].VirtualAddress,
sects[i].SizeOfRawData,
sects[i].PointerToRawData,
sects[i].PointerToRelocations,
sects[i].PointerToLinenumbers,
sects[i].NumberOfRelocations,
sects[i].NumberOfLinenumbers,
sects[i].Characteristics
);
}
for (; n != 0x200; ) {
n += ::write_bytes(
out,
(unsigned char)0
);
}
return n;
}
template<typename OutputIterator>
SPROUT_CXX14_CONSTEXPR std::size_t
write_idata(OutputIterator& out, std::size_t n = 0) {
SPROUT_CONSTEXPR int idt[] = {
// IDT 1
0x5028, 0, 0, 0x5034, 0x5044,
// IDT (終端)
0, 0, 0, 0, 0
};
n += ::write_bytes(
out,
idt
);
SPROUT_CONSTEXPR int ilt_iat[] = {
0x5050, 0x505a, 0
};
// ILT
n += ::write_bytes(
out,
ilt_iat
);
n += ::write_bytes(
out,
"msvcrt.dll\0\0\0\0\0"
);
// IAT
n += ::write_bytes(
out,
ilt_iat
);
n += ::write_bytes(
out,
(std::int16_t)0,
"putchar",
(std::int16_t)0,
"getchar"
);
for (; n != 0x400; ) {
n += ::write_bytes(
out,
(unsigned char)0
);
}
return n;
}
//
// コンパイル
//
template<std::size_t LoopLimit = 256, typename InputIterator, typename RandomAccessIterator>
SPROUT_CXX14_CONSTEXPR std::size_t
compile(InputIterator first, InputIterator last, RandomAccessIterator& out_first) {
sprout::array<int, LoopLimit> loops {{}}; // ループを保存するスタック
auto loop_first = sprout::begin(loops);
auto loop_last = sprout::end(loops);
auto loop = loop_first;
int idx = 0;
auto out = out_first;
idx += ::write_bytes(
out,
(unsigned char)0x31, (unsigned char)0xc9, // xor ecx, ecx
(unsigned char)0x57, // push edi
(unsigned char)0xbf, ::addr_buf // mov edi, addr_buf
);
for (; first != last; ++first) {
switch (*first) {
case '>':
idx += ::write_bytes(
out,
(unsigned char)0x66, (unsigned char)0x41 // inc cx
);
break;
case '<':
idx += ::write_bytes(
out,
(unsigned char)0x66, (unsigned char)0x49 // dec cx
);
break;
case '+':
idx += ::write_bytes(
out,
(unsigned char)0xfe, (unsigned char)0x04, (unsigned char)0x0f // inc byte [edi+ecx]
);
break;
case '-':
idx += ::write_bytes(
out,
(unsigned char)0xfe, (unsigned char)0x0c, (unsigned char)0x0f // dec byte [edi+ecx]
);
break;
case '.':
idx += ::write_bytes(
out,
(unsigned char)0x51, // push ecx
(unsigned char)0x0f, (unsigned char)0xb6, (unsigned char)0x04, (unsigned char)0x0f, // movzx eax,byte [edi+ecx]
(unsigned char)0x50, // push eax
(unsigned char)0xa1, ::addr_putchar, // mov eax, [addr_putchar]
(unsigned char)0xff, (unsigned char)0xd0, // call eax
(unsigned char)0x58, // pop eax
(unsigned char)0x59 // pop ecx
);
break;
case ',':
idx += ::write_bytes(
out,
(unsigned char)0x51, // push ecx
(unsigned char)0xa1, ::addr_getchar, // mov eax, [addr_getchar]
(unsigned char)0xff, (unsigned char)0xd0, // call eax
(unsigned char)0x59, // pop ecx
(unsigned char)0x88, (unsigned char)0x04, (unsigned char)0x0f // mov [edi+ecx],al
);
break;
case '[':
SPROUT_ASSERT_MSG(loop != loop_last, "loop overflow");
*loop++ = idx; // インデックスをスタックに積む
idx += ::write_bytes(
out,
(unsigned char)0x80, (unsigned char)0x3c, (unsigned char)0x0f, (unsigned char)0x00, // cmp byte [edi+ecx],0
(unsigned char)0x0f, (unsigned char)0x84, // jz 対応する]の直後
(unsigned char)0xde, (unsigned char)0xad, (unsigned char)0xbe, (unsigned char)0xef // (アドレスは後で決定)
);
break;
case ']':
{
SPROUT_ASSERT_MSG(loop != loop_first, "missing '['");
int idx_loop = *--loop;
idx += ::write_bytes(
out,
(unsigned char)0xe9, (std::int32_t)(idx_loop - (idx + 5)) // jmp idx_loop
);
auto out_loop = out_first + (idx_loop + 6);
::write_bytes(
out_loop,
(std::int32_t)(idx - (idx_loop + 10)) // (アドレス)
);
break;
}
}
SPROUT_ASSERT_MSG(idx <= (int)::bin_size - 32, "buffer overflow");
}
SPROUT_ASSERT_MSG(loop == loop_first, "missing ']'");
// 終了処理
idx += ::write_bytes(
out,
(unsigned char)0x5f, // pop edi
(unsigned char)0x31, (unsigned char)0xc0, // xor eax, eax
(unsigned char)0xc3 // ret
);
return idx;
}
//
// ビルド
//
template<std::size_t LoopLimit = 256, typename InputIterator, typename RandomAccessIterator>
SPROUT_CXX14_CONSTEXPR std::size_t
build(InputIterator first, InputIterator last, RandomAccessIterator& out) {
std::size_t n = 0;
n += ::write_pe_header(out, n); // ヘッダ出力
n += ::write_idata(out, n); // .idataセクション出力
n += ::compile<LoopLimit>(first, last, out); // コンパイル
return n;
}
SPROUT_CXX14_CONSTEXPR sprout::sub_array<sprout::array<unsigned char, ::bin_size> >
build_brainfuck() {
sprout::array<unsigned char, ::bin_size> bin{{}};
auto out = sprout::begin(bin);
auto n = ::build<::loop_limit>(sprout::begin(::source), sprout::end(::source), out);
return sprout::sub_copy(bin, 0, n);
}
int main(int argc, char* argv[]) {
SPROUT_CXX14_CONSTEXPR auto bin = ::build_brainfuck();
char const* filename = argc >= 2 ? argv[1]
: "a.exe"
;
std::ofstream ofs(filename);
if (!ofs) {
std::cout
<< "could not open file" << std::endl
;
return -1;
}
sprout::range::copy(bin, std::ostreambuf_iterator<char>(ofs));
}

204
example/perceptron/g3.cpp Normal file
View file

@ -0,0 +1,204 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/array.hpp>
#include <sprout/algorithm/copy.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/math/sigmoid.hpp>
#include <sprout/random/uniform_01.hpp>
#include <sprout/random/generate_array.hpp>
#include <sprout/assert.hpp>
//
// perceptron
//
template<typename FloatType, std::size_t In, std::size_t Hid, std::size_t Out>
class perceptron {
public:
typedef FloatType value_type;
private:
struct worker {
public:
// 入力
sprout::array<value_type, In + 1> xi1;
sprout::array<value_type, Hid + 1> xi2;
sprout::array<value_type, Out> xi3;
// 出力
sprout::array<value_type, In + 1> o1;
sprout::array<value_type, Hid + 1> o2;
sprout::array<value_type, Out> o3;
};
private:
// 誤差
sprout::array<value_type, Hid + 1> d2;
sprout::array<value_type, Out> d3;
// 重み
sprout::array<value_type, (In + 1) * Hid> w1;
sprout::array<value_type, (Hid + 1) * Out> w2;
private:
// 順伝播
template<typename ForwardIterator>
SPROUT_CXX14_CONSTEXPR void
forward_propagation(ForwardIterator in_first, ForwardIterator in_last, worker& work) const {
// 入力層の順伝播
sprout::copy(in_first, in_last, sprout::begin(work.xi1));
work.xi1[In] = 1;
sprout::copy(sprout::begin(work.xi1), sprout::end(work.xi1), sprout::begin(work.o1));
// 隠れ層の順伝播
for (std::size_t i = 0; i != Hid; ++i) {
work.xi2[i] = 0;
for (std::size_t j = 0; j != In + 1; ++j) {
work.xi2[i] += w1[j * Hid + i] * work.o1[j];
}
work.o2[i] = sprout::math::sigmoid(work.xi2[i]);
}
work.o2[Hid] = 1;
// 出力層の順伝播
for (std::size_t i = 0; i != Hid; ++i) {
work.xi3[i] = 0;
for (std::size_t j = 0; j != In + 1; ++j) {
work.xi3[i] += w2[j * Out + i] * work.o2[j];
}
work.o3[i] = work.xi3[i];
}
}
public:
template<typename RandomNumberGenerator>
explicit SPROUT_CXX14_CONSTEXPR perceptron(RandomNumberGenerator& rng)
: d2{{}}, d3{{}}
, w1(sprout::random::generate_array<(In + 1) * Hid>(rng, sprout::random::uniform_01<value_type>()))
, w2(sprout::random::generate_array<(Hid + 1) * Out>(rng, sprout::random::uniform_01<value_type>()))
{}
// ニューラルネットの訓練
// [in_first, in_last) : 訓練データ (N*In 個)
// [t_first, t_last) : 教師データ (N 個)
template<typename ForwardIterator1, typename ForwardIterator2>
SPROUT_CXX14_CONSTEXPR void
train(
ForwardIterator1 in_first, ForwardIterator1 in_last,
ForwardIterator2 t_first, ForwardIterator2 t_last,
std::size_t repeat = 1000, value_type eta = value_type(0.1)
)
{
SPROUT_ASSERT(sprout::distance(in_first, in_last) % In == 0);
SPROUT_ASSERT(sprout::distance(in_first, in_last) / In == sprout::distance(t_first, t_last));
worker work{};
for (std::size_t times = 0; times != repeat; ++times) {
ForwardIterator1 in_it = in_first;
ForwardIterator2 t_it = t_first;
for (; in_it != in_last; sprout::advance(in_it, In), ++t_it) {
// 順伝播
forward_propagation(in_it, sprout::next(in_it, In), work);
// 出力層の誤差計算
for (std::size_t i = 0; i != Out; ++i) {
d3[i] = *t_it == i ? work.o3[i] - 1
: work.o3[i]
;
}
// 出力層の重み更新
for (std::size_t i = 0; i != Hid + 1; ++i) {
for (std::size_t j = 0; j != Out; ++j) {
w2[i * Out + j] -= eta * d3[j] * work.o2[i];
}
}
// 隠れ層の誤差計算
for (std::size_t i = 0; i != Hid + 1; ++i) {
d2[i] = 0;
for (std::size_t j = 0; j != Out; ++j) {
d2[i] += w2[i * Out + j] * d3[j];
}
d2[i] *= sprout::math::d_sigmoid(work.xi2[i]);
}
// 隠れ層の重み更新
for (std::size_t i = 0; i != In + 1; ++i) {
for (std::size_t j = 0; j != Hid; ++j) {
w1[i * Hid + j] -= eta * d2[j] * work.o1[i];
}
}
}
}
}
// 与えられたデータに対して最も可能性の高いクラスを返す
template<typename ForwardIterator>
SPROUT_CXX14_CONSTEXPR std::size_t
predict(ForwardIterator in_first, ForwardIterator in_last) const {
SPROUT_ASSERT(sprout::distance(in_first, in_last) == In);
worker work{};
// 順伝播による予測
forward_propagation(in_first, in_last, work);
// 出力が最大になるクラスを判定
return sprout::distance(
sprout::begin(work.o3),
sprout::max_element(sprout::begin(work.o3), sprout::end(work.o3))
);
}
};
#include <cstddef>
#include <iostream>
#include <sprout/config.hpp>
#include <sprout/random/default_random_engine.hpp>
#include <sprout/random/unique_seed.hpp>
#include <sprout/static_assert.hpp>
// 訓練データ
SPROUT_CONSTEXPR auto train_data = sprout::make_array<double>(
# include "g3_train.csv"
);
// 教師データ
SPROUT_CONSTEXPR auto teach_data = sprout::make_array<std::size_t>(
# include "g3_teach.csv"
);
SPROUT_STATIC_ASSERT(train_data.size() % 2 == 0);
SPROUT_STATIC_ASSERT(train_data.size() / 2 == teach_data.size());
// 訓練済みパーセプトロンを生成
template<typename FloatType, std::size_t In, std::size_t Hid, std::size_t Out>
SPROUT_CXX14_CONSTEXPR ::perceptron<FloatType, In, Hid, Out>
make_trained_perceptron() {
// 乱数生成器
sprout::random::default_random_engine rng(SPROUT_UNIQUE_SEED);
// パーセプトロン
::perceptron<FloatType, In, Hid, Out> per(rng);
// 訓練
per.train(
train_data.begin(), train_data.end(),
teach_data.begin(), teach_data.end(),
500, 0.1
);
return per;
}
int main() {
// パーセプトロンを生成入力2 隠れ3 出力3
SPROUT_CXX14_CONSTEXPR auto per = ::make_trained_perceptron<double, 2, 3, 3>();
// 結果の表示
for (auto it = train_data.begin(), last = train_data.end(); it != last; it += 2) {
std::cout << per.predict(it, it + 2) << std::endl;
}
}

View file

@ -0,0 +1,150 @@
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
Can't render this file because it has a wrong number of fields in line 150.

View file

@ -0,0 +1,150 @@
2.838248351,-0.057127115,
2.84962986,0.30984388,
3.069875981,0.069165603,
3.033612564,0.237406102,
3.162983688,0.334387888,
3.163831849,0.487806933,
2.997986085,0.061074061,
2.799347441,0.521430032,
3.137156052,0.266393153,
2.870857355,0.267030982,
3.43934308,0.170662698,
3.035552198,0.251317543,
2.886143741,0.125075012,
3.221207099,0.030493356,
3.050238248,0.007279557,
2.733967037,0.235668448,
3.153513285,-0.010778431,
3.311231402,0.343325475,
3.298245949,0.065857414,
2.848633328,-0.004875479,
3.070831457,0.211490982,
3.082296334,0.31440897,
2.926651655,-0.240105616,
2.978054772,0.031004937,
2.35804167,0.239646483,
2.645048857,0.159202643,
2.932230736,0.104463435,
3.097376157,0.150507296,
2.803701193,0.042427284,
2.953016638,0.28536828,
3.238065532,0.346081055,
3.055363223,0.445131721,
2.995237434,0.507696093,
2.804479208,0.245421171,
3.012620496,0.384000638,
2.693411745,0.312330244,
3.102647408,0.343171956,
2.896095389,0.036131501,
2.718440992,-0.01150165,
3.170644375,-0.048096883,
3.011452172,0.034237664,
2.872141309,0.07956016,
2.865096742,0.008559658,
3.279540305,0.302372444,
2.860098477,0.218127155,
3.269317565,-0.005452377,
2.761144719,0.673127168,
2.902469266,0.361832898,
3.11297363,0.50154383,
3.025469568,0.399359182,
1.840419314,1.905105063,
1.813240148,1.813839986,
2.123039813,2.132571185,
1.946192802,1.773046885,
1.969172236,1.805946832,
2.258526017,2.000929535,
1.864577066,2.144995459,
1.911976195,1.980181472,
1.990154583,1.919792502,
1.769958598,2.105082362,
2.137578551,1.944983188,
2.00439482,2.072477229,
1.927718762,1.694463892,
2.207399026,1.851368634,
2.495855335,1.78918729,
2.381107166,2.040305134,
2.05695779,2.458901875,
1.782594688,2.133780789,
1.731552089,2.188212826,
2.157206504,2.249346956,
1.771550549,2.388096625,
1.596862739,2.285617904,
2.116253295,2.043142148,
2.051844958,2.033143301,
1.931137989,2.426396361,
1.987232105,2.141510946,
2.265269874,2.150853439,
2.02603174,2.015376408,
1.95851869,2.243280964,
1.982323697,1.705817048,
1.860646929,2.221006838,
1.850979072,2.557549512,
2.245893751,1.851633418,
2.225460386,1.968984437,
1.817314806,2.306871098,
2.28503916,2.17214804,
1.974994597,1.313041694,
2.031987688,2.022965729,
1.953448998,2.261221941,
2.167787963,1.950768156,
2.325040244,1.533073263,
2.058211845,2.0741863,
2.047485215,2.098219462,
2.228436076,1.920446541,
2.328240588,2.151820146,
2.183441475,2.292478916,
2.190968871,1.760135247,
1.716478165,2.078620922,
1.878852022,2.15075819,
2.085908678,1.96855502,
3.798041143,2.925502959,
3.835899929,3.004531872,
4.226026357,3.327911034,
3.63906142,2.764149093,
3.976732793,2.765971538,
3.735533807,3.211145512,
3.922743188,2.908463331,
3.959548749,2.92371863,
4.220358369,3.028638464,
4.101855229,2.860451817,
3.818023487,2.821524824,
3.944688596,3.251039443,
4.139128323,3.071444196,
4.235165326,3.005161748,
4.248626372,3.156115907,
4.286060111,2.952368701,
3.974827507,2.924985851,
4.140698521,3.042471222,
4.31503215,2.912715016,
4.41718743,3.064667839,
3.894120786,2.925224863,
3.953199682,3.348500249,
4.003736459,3.208318835,
3.872457887,2.698607706,
3.889675701,2.977512411,
3.974258739,3.099134752,
3.794940485,3.033699013,
4.020409067,2.784229901,
3.851699136,2.972769818,
4.036060943,3.066876325,
3.590866735,3.062219821,
4.000802489,3.041278742,
4.254308353,2.947953876,
4.126845488,2.932815351,
3.807568611,3.145490402,
3.986677755,3.378673859,
3.684653059,2.911221769,
4.259008498,3.374089548,
3.964802614,3.072807287,
4.182124157,2.950380575,
3.948426268,3.099264552,
4.053742816,3.195652528,
4.340603893,3.098341999,
3.67327559,2.94969907,
4.043519751,3.311304107,
3.97872525,3.166533465,
4.19023214,2.962725503,
3.717902917,2.75762358,
3.947763326,3.160248033,
4.191797555,3.162533112
Can't render this file because it has a wrong number of fields in line 150.

View file

@ -18,6 +18,12 @@ namespace sprout {
struct float_compute struct float_compute
: public sprout::float_promote<double, Types...> : public sprout::float_promote<double, Types...>
{}; {};
template<typename FloatType>
inline SPROUT_CONSTEXPR typename sprout::math::detail::float_compute<FloatType>::type
as_float_compute(FloatType const& x) {
return static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x);
}
} // namespace detail } // namespace detail
} // namespace math } // namespace math
} // namespace sprout } // namespace sprout

View file

@ -15,5 +15,6 @@
#include <sprout/math/bernoulli.hpp> #include <sprout/math/bernoulli.hpp>
#include <sprout/math/comparisons.hpp> #include <sprout/math/comparisons.hpp>
#include <sprout/math/integer.hpp> #include <sprout/math/integer.hpp>
#include <sprout/math/sigmoid.hpp>
#endif // #ifndef SPROUT_MATH_FUNCTIONS_HPP #endif // #ifndef SPROUT_MATH_FUNCTIONS_HPP

203
sprout/math/sigmoid.hpp Normal file
View file

@ -0,0 +1,203 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_MATH_SIGMOID_HPP
#define SPROUT_MATH_SIGMOID_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
//
// sigmoid
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
sigmoid_impl(T x){
return 1 / (1 + sprout::math::exp(-x));
}
template<typename T>
inline SPROUT_CONSTEXPR T
sigmoid_impl(T x, T a){
return sprout::math::detail::sigmoid_impl(a * x);
}
} // namespace detail
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
sigmoid(FloatType x){
return sprout::math::detail::sigmoid_impl(sprout::math::detail::as_float_compute(x));
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
sigmoid(FloatType x, FloatType a){
return sprout::math::detail::sigmoid_impl(sprout::math::detail::as_float_compute(x), sprout::math::detail::as_float_compute(a));
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
sigmoid(IntType x) {
return sprout::math::sigmoid(static_cast<double>(x));
}
template<
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type
sigmoid(ArithmeticType1 x, ArithmeticType2 a) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::sigmoid(static_cast<type>(x), static_cast<type>(a));
}
//
// d_sigmoid
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
d_sigmoid_impl_1(T s){
return s * (1 - s);
}
template<typename T>
inline SPROUT_CONSTEXPR T
d_sigmoid_impl_1(T s, T a){
return a * s * (1 - s);
}
template<typename T>
inline SPROUT_CONSTEXPR T
d_sigmoid_impl(T x){
return sprout::math::detail::d_sigmoid_impl_1(sprout::math::sigmoid(x));
}
template<typename T>
inline SPROUT_CONSTEXPR T
d_sigmoid_impl(T x, T a){
return sprout::math::detail::d_sigmoid_impl_1(sprout::math::sigmoid(x, a), a);
}
} // namespace detail
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
d_sigmoid(FloatType x){
return sprout::math::detail::d_sigmoid_impl(sprout::math::detail::as_float_compute(x));
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
d_sigmoid(FloatType x, FloatType a){
return sprout::math::detail::d_sigmoid_impl(sprout::math::detail::as_float_compute(x), sprout::math::detail::as_float_compute(a));
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
d_sigmoid(IntType x) {
return sprout::math::d_sigmoid(static_cast<double>(x));
}
template<
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type
d_sigmoid(ArithmeticType1 x, ArithmeticType2 a) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::d_sigmoid(static_cast<type>(x), static_cast<type>(a));
}
//
// d2_sigmoid
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
d2_sigmoid_impl_1(T s){
return s * (1 - s) * (1 - 2 * s);
}
template<typename T>
inline SPROUT_CONSTEXPR T
d2_sigmoid_impl_1(T s, T a){
return a * a * s * (1 - s) * (1 - 2 * s);
}
template<typename T>
inline SPROUT_CONSTEXPR T
d2_sigmoid_impl(T x){
return sprout::math::detail::d2_sigmoid_impl_1(sprout::math::sigmoid(x));
}
template<typename T>
inline SPROUT_CONSTEXPR T
d2_sigmoid_impl(T x, T a){
return sprout::math::detail::d2_sigmoid_impl_1(sprout::math::sigmoid(x, a), a);
}
} // namespace detail
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
d2_sigmoid(FloatType x){
return sprout::math::detail::d2_sigmoid_impl(sprout::math::detail::as_float_compute(x));
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
d2_sigmoid(FloatType x, FloatType a){
return sprout::math::detail::d2_sigmoid_impl(sprout::math::detail::as_float_compute(x), sprout::math::detail::as_float_compute(a));
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
d2_sigmoid(IntType x) {
return sprout::math::d2_sigmoid(static_cast<double>(x));
}
template<
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type
d2_sigmoid(ArithmeticType1 x, ArithmeticType2 a) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::d2_sigmoid(static_cast<type>(x), static_cast<type>(a));
}
} // namespace math
using sprout::math::sigmoid;
using sprout::math::d_sigmoid;
using sprout::math::d2_sigmoid;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_SIGMOID_HPP

View file

@ -8,9 +8,11 @@
#ifndef SPROUT_RANDOM_GENERATE_ARRAY_HPP #ifndef SPROUT_RANDOM_GENERATE_ARRAY_HPP
#define SPROUT_RANDOM_GENERATE_ARRAY_HPP #define SPROUT_RANDOM_GENERATE_ARRAY_HPP
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp> #include <sprout/workaround/std/cstddef.hpp>
#include <sprout/array/array.hpp> #include <sprout/array/array.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/pair/pair.hpp> #include <sprout/utility/pair/pair.hpp>
#include <sprout/random/results.hpp> #include <sprout/random/results.hpp>
#include <sprout/generator/results.hpp> #include <sprout/generator/results.hpp>
@ -29,6 +31,15 @@ namespace sprout {
} }
return result; return result;
} }
template<std::size_t N, typename RandomNumberGenerator, typename Distribution>
inline SPROUT_CXX14_CONSTEXPR sprout::array<typename std::remove_reference<Distribution>::type::result_type, N>
generate_array(RandomNumberGenerator& rng, Distribution&& dist) {
sprout::array<typename std::remove_reference<Distribution>::type::result_type, N> result{{}};
for (std::size_t i = 0; i != N; ++i) {
result[i] = SPROUT_FORWARD(Distribution, dist)(rng);
}
return result;
}
namespace detail { namespace detail {
template<std::size_t N, typename RandomNumberGenerator, typename Random, typename... Args> template<std::size_t N, typename RandomNumberGenerator, typename Random, typename... Args>

View file

@ -32,30 +32,56 @@ test_cpp=$(cd $(dirname $0); pwd)/test.cpp
test_py=$(cd $(dirname $0); pwd)/test.py test_py=$(cd $(dirname $0); pwd)/test.py
get_std_option() { get_std_option() {
if [ "${3}" = "c++1y" ]; then vn=0
if [ "${2}" = "." ]; then
if [ "${1}" = "gcc" ]; then if [ "${1}" = "gcc" ]; then
if [ "${2}" = "." ]; then read -ra current_version_array <<< `g++ --version`
echo -n "-std=c++1y" vn=${current_version_array[2]//.}
elif [ "${2//.}" -lt "480" ]; then elif [ "${1}" = "clang" ]; then
read -ra current_version_array <<< `clang++ --version`
vn=${current_version_array[2]//.}
fi
else
vn=${2//.}
fi
if [ "${3}" = "c++17" -o "${3}" = "c++1z" ]; then
if [ "${1}" = "gcc" ]; then
if [ "${vn}" -lt "480" ]; then
echo -n "-std=c++11" echo -n "-std=c++11"
else else
echo -n "-std=c++1y" echo -n "-std=c++1y"
fi fi
elif [ "${1}" = "clang" ]; then elif [ "${1}" = "clang" ]; then
if [ "${2}" = "." ]; then if [ "${vn}" -lt "32" ]; then
echo -n "-std=c++11"
elif [ "${vn}" -lt "350" ]; then
echo -n "-std=c++1y" echo -n "-std=c++1y"
elif [ "${2//.}" -lt "32" ]; then else
echo -n "-std=c++1z"
fi
fi
elif [ "${3}" = "c++14" -o "${3}" = "c++1y" ]; then
if [ "${1}" = "gcc" ]; then
if [ "${vn}" -lt "480" ]; then
echo -n "-std=c++11" echo -n "-std=c++11"
else else
echo -n "-std=c++1y" echo -n "-std=c++1y"
fi fi
elif [ "${1}" = "clang" ]; then
if [ "${vn}" -lt "32" ]; then
echo -n "-std=c++11"
elif [ "${vn}" -lt "350" ]; then
echo -n "-std=c++1y"
else
echo -n "-std=c++14"
fi
fi fi
else else
echo -n "-std=c++11" echo -n "-std=c++11"
fi fi
} }
args=`getopt -o S:g:c:O:C:V:D:I:P:f -l stagedir:,gcc-version:,clang-version:,gcc-root:,clang-root:,std:,option:,compiler-option:,version-option:,define:,include:,max-procs:,force,help -- "$@"` args=`getopt -o S:s:g:c:O:C:V:D:I:P:f -l stagedir:,source:,gcc-version:,clang-version:,gcc-root:,clang-root:,std:,option:,compiler-option:,version-option:,define:,include:,max-procs:,force,help -- "$@"`
if [ "$?" -ne 0 ]; then if [ "$?" -ne 0 ]; then
echo >&2 "error: options parse error. See 'test.sh --help'" echo >&2 "error: options parse error. See 'test.sh --help'"
exit 1 exit 1
@ -64,6 +90,7 @@ eval set -- ${args}
while [ -n "$1" ]; do while [ -n "$1" ]; do
case $1 in case $1 in
-S|--stagedir) stagedir=$2; shift 2;; -S|--stagedir) stagedir=$2; shift 2;;
-s|--source) test_cpp=$2; shift 2;;
-g|--gcc-version) gcc_version="$2"; shift 2;; -g|--gcc-version) gcc_version="$2"; shift 2;;
-c|--clang-version) clang_version="$2"; shift 2;; -c|--clang-version) clang_version="$2"; shift 2;;
--gcc-root) gcc_root="$2"; shift 2;; --gcc-root) gcc_root="$2"; shift 2;;
@ -88,6 +115,9 @@ if [ ${use_help} -ne 0 ]; then
echo " -S, --stagedir=<dir> Output files here." echo " -S, --stagedir=<dir> Output files here."
echo " Default; 'testspr'" echo " Default; 'testspr'"
echo "" echo ""
echo " -s, --source=<file> C++ source file."
echo " Default; './test.cpp'"
echo ""
echo " -g, --gcc-version=<list> Indicates gcc version list (space separated)." echo " -g, --gcc-version=<list> Indicates gcc version list (space separated)."
echo " If '.', version that is installed on the system." echo " If '.', version that is installed on the system."
echo " Default; '.'" echo " Default; '.'"
@ -115,7 +145,7 @@ if [ ${use_help} -ne 0 ]; then
echo "" echo ""
echo " -D, --define=<identifier> Define macro for preprocessor." echo " -D, --define=<identifier> Define macro for preprocessor."
echo "" echo ""
echo " -I, --include=<directory> Add system include path." echo " -I, --include=<dir> Add system include path."
echo "" echo ""
echo " -P, --max-procs=<value> The maximum number of process use." echo " -P, --max-procs=<value> The maximum number of process use."
echo " If other than null, processing in parallel mode." echo " If other than null, processing in parallel mode."
@ -129,6 +159,7 @@ fi
echo "settings:" echo "settings:"
echo " stagedir = '${stagedir}'" echo " stagedir = '${stagedir}'"
echo " source = '${test_cpp}'"
echo " gcc-version = (${gcc_version})" echo " gcc-version = (${gcc_version})"
echo " clang-version = (${clang_version})" echo " clang-version = (${clang_version})"
echo " gcc-root = '${gcc_root}'" echo " gcc-root = '${gcc_root}'"