#include <algorithm>
#include <functional>
#include <cstddef>
#include <cstring>
#define NS aslib
// #define NS std
// ↑ユーザー定義型用の完全特殊化以外をstd名前空間に記述するのは本当は×
#define RUN
namespace {
template<typename Itr>
Itr find_detail_for_char2darray(Itr begin, Itr end, const char *target) {
return std::find_if(begin, end,
std::not1(std::bind2nd(std::ptr_fun(std::strcmp), target))
);
}
}
namespace NS {
template<std::size_t N>
const char (*find(const char (*begin)[N], const char (*end)[N], const char *target))[N] {
return ::find_detail_for_char2darray(begin, end, target);
}
#if NS==std
// std下に置く場合は、以下の特殊化の定義も必要となる
template<std::size_t N>
char (*find(char (*begin)[N], char (*end)[N], const char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
template<std::size_t N>
const char (*find(const char (*begin)[N], const char (*end)[N], char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
template<std::size_t N>
char (*find(char (*begin)[N], char (*end)[N], char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
#endif
}
#ifdef RUN
#include <cassert>
int main()
{
const char month[][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const std::size_t monthNum = sizeof(month) / sizeof(month[0]);
char wday[][4] = {
"Sun", "Mon", "Tue", "Web", "Thu", "Fri", "Sat"
};
const std::size_t wdayNum = sizeof(wday) / sizeof(wday[0]);
char target[4];
assert(NS::find(month, month + monthNum, "Jan") == &month[0]);
assert(NS::find(month, month + monthNum, "XXX") == month + monthNum);
assert(NS::find(wday, wday + wdayNum, "Sun") == &wday[0]);
std::strcpy(target, "Feb");
assert(NS::find(month, month + monthNum, target) == &month[1]);
std::strcpy(target, "Mon");
assert(NS::find(wday, wday + wdayNum, target) == &wday[1]);
}
#endif
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxjc3RkZGVmPgojaW5jbHVkZSA8Y3N0cmluZz4KCiNkZWZpbmUgTlMgYXNsaWIKLy8gI2RlZmluZSBOUyBzdGQKLy8g4oaR44Om44O844K244O85a6a576p5Z6L55So44Gu5a6M5YWo54m55q6K5YyW5Lul5aSW44KSc3Rk5ZCN5YmN56m66ZaT44Gr6KiY6L+w44GZ44KL44Gu44Gv5pys5b2T44Gvw5cKCiNkZWZpbmUgUlVOCgpuYW1lc3BhY2UgewoJdGVtcGxhdGU8dHlwZW5hbWUgSXRyPgoJSXRyIGZpbmRfZGV0YWlsX2Zvcl9jaGFyMmRhcnJheShJdHIgYmVnaW4sIEl0ciBlbmQsIGNvbnN0IGNoYXIgKnRhcmdldCkgewoJCXJldHVybiBzdGQ6OmZpbmRfaWYoYmVnaW4sIGVuZCwgCgkJCXN0ZDo6bm90MShzdGQ6OmJpbmQybmQoc3RkOjpwdHJfZnVuKHN0ZDo6c3RyY21wKSwgdGFyZ2V0KSkKCQkpOwoJfQp9CgpuYW1lc3BhY2UgTlMgewoJdGVtcGxhdGU8c3RkOjpzaXplX3QgTj4KCWNvbnN0IGNoYXIgKCpmaW5kKGNvbnN0IGNoYXIgKCpiZWdpbilbTl0sIGNvbnN0IGNoYXIgKCplbmQpW05dLCBjb25zdCBjaGFyICp0YXJnZXQpKVtOXSB7CgkJcmV0dXJuIDo6ZmluZF9kZXRhaWxfZm9yX2NoYXIyZGFycmF5KGJlZ2luLCBlbmQsIHRhcmdldCk7Cgl9CgojaWYgTlM9PXN0ZAoJLy8gc3Rk5LiL44Gr572u44GP5aC05ZCI44Gv44CB5Lul5LiL44Gu54m55q6K5YyW44Gu5a6a576p44KC5b+F6KaB44Go44Gq44KLCgoJdGVtcGxhdGU8c3RkOjpzaXplX3QgTj4KCWNoYXIgKCpmaW5kKGNoYXIgKCpiZWdpbilbTl0sIGNoYXIgKCplbmQpW05dLCBjb25zdCBjaGFyICp0YXJnZXQpKVtOXSB7CgkJcmV0dXJuIGZpbmRfZGV0YWlsX2Zvcl9jaGFyMmRhcnJheShiZWdpbiwgZW5kLCB0YXJnZXQpOwoJfQoKCXRlbXBsYXRlPHN0ZDo6c2l6ZV90IE4+Cgljb25zdCBjaGFyICgqZmluZChjb25zdCBjaGFyICgqYmVnaW4pW05dLCBjb25zdCBjaGFyICgqZW5kKVtOXSwgY2hhciAqdGFyZ2V0KSlbTl0gewoJCXJldHVybiBmaW5kX2RldGFpbF9mb3JfY2hhcjJkYXJyYXkoYmVnaW4sIGVuZCwgdGFyZ2V0KTsKCX0KCgl0ZW1wbGF0ZTxzdGQ6OnNpemVfdCBOPgoJY2hhciAoKmZpbmQoY2hhciAoKmJlZ2luKVtOXSwgY2hhciAoKmVuZClbTl0sIGNoYXIgKnRhcmdldCkpW05dIHsKCQlyZXR1cm4gZmluZF9kZXRhaWxfZm9yX2NoYXIyZGFycmF5KGJlZ2luLCBlbmQsIHRhcmdldCk7Cgl9CiNlbmRpZgp9CgojaWZkZWYgUlVOCiNpbmNsdWRlIDxjYXNzZXJ0PgppbnQgbWFpbigpCnsKCWNvbnN0IGNoYXIgbW9udGhbXVs0XSA9IHsKCQkiSmFuIiwgIkZlYiIsICJNYXIiLCAiQXByIiwgIk1heSIsICJKdW4iLAoJCSJKdWwiLCAiQXVnIiwgIlNlcCIsICJPY3QiLCAiTm92IiwgIkRlYyIKCX07Cgljb25zdCBzdGQ6OnNpemVfdCBtb250aE51bSA9IHNpemVvZihtb250aCkgLyBzaXplb2YobW9udGhbMF0pOwoKCWNoYXIgd2RheVtdWzRdID0gewoJCSJTdW4iLCAiTW9uIiwgIlR1ZSIsICJXZWIiLCAiVGh1IiwgIkZyaSIsICJTYXQiCgl9OwoJY29uc3Qgc3RkOjpzaXplX3Qgd2RheU51bSA9IHNpemVvZih3ZGF5KSAvIHNpemVvZih3ZGF5WzBdKTsKCgljaGFyIHRhcmdldFs0XTsKCglhc3NlcnQoTlM6OmZpbmQobW9udGgsIG1vbnRoICsgbW9udGhOdW0sICJKYW4iKSA9PSAmbW9udGhbMF0pOwoJYXNzZXJ0KE5TOjpmaW5kKG1vbnRoLCBtb250aCArIG1vbnRoTnVtLCAiWFhYIikgPT0gbW9udGggKyBtb250aE51bSk7CgoJYXNzZXJ0KE5TOjpmaW5kKHdkYXksIHdkYXkgKyB3ZGF5TnVtLCAiU3VuIikgPT0gJndkYXlbMF0pOwoKCXN0ZDo6c3RyY3B5KHRhcmdldCwgIkZlYiIpOwoJYXNzZXJ0KE5TOjpmaW5kKG1vbnRoLCBtb250aCArIG1vbnRoTnVtLCB0YXJnZXQpID09ICZtb250aFsxXSk7CgoJc3RkOjpzdHJjcHkodGFyZ2V0LCAiTW9uIik7Cglhc3NlcnQoTlM6OmZpbmQod2RheSwgd2RheSArIHdkYXlOdW0sIHRhcmdldCkgPT0gJndkYXlbMV0pOwp9CiNlbmRpZgo=