#include <type_traits>
#include <iostream>
template <typename T>
struct has_begin
{
typedef char (& yes)[1];
typedef char (& no)[2];
template <typename U>
static yes deduce(decltype(std::begin(std::declval<U const &>())) *);
template <typename> static no deduce(...);
static bool constexpr value = sizeof(deduce<T>(0)) == sizeof(yes);
};
template <typename Range>
struct range_elem_i
{
typedef typename std::decay<
decltype(*std::begin(std::declval<Range const &>()))
>::type type;
};
template <typename T> using range_elem = typename range_elem_i<T>::type;
template <
typename Range,
typename = typename std::enable_if<has_begin<Range>::value>::type
>
int count(Range const & range, range_elem<Range> value)
{
int n = 0;
for(auto const & e : range) if(e==value) ++n;
return n;
}
struct S {};
int count(S const & s, int) { return 10; }
int main()
{
int arr[] = { 1, 2, 2, 3 };
std::cout << count(arr, 2) << '\n';
S s;
std::cout << count(s, 1) << '\n';
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CgoJdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CglzdHJ1Y3QgaGFzX2JlZ2luCgl7CgkJdHlwZWRlZiBjaGFyICgmIHllcylbMV07CgkJdHlwZWRlZiBjaGFyICgmIG5vKVsyXTsKCgkJdGVtcGxhdGUgPHR5cGVuYW1lIFU+CgkJc3RhdGljIHllcyBkZWR1Y2UoZGVjbHR5cGUoc3RkOjpiZWdpbihzdGQ6OmRlY2x2YWw8VSBjb25zdCAmPigpKSkgKik7CgkJdGVtcGxhdGUgPHR5cGVuYW1lPiBzdGF0aWMgbm8gZGVkdWNlKC4uLik7CgoJCXN0YXRpYyBib29sIGNvbnN0ZXhwciB2YWx1ZSA9IHNpemVvZihkZWR1Y2U8VD4oMCkpID09IHNpemVvZih5ZXMpOwoJfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBSYW5nZT4Kc3RydWN0IHJhbmdlX2VsZW1faQp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6ZGVjYXk8CiAgICAgICAgZGVjbHR5cGUoKnN0ZDo6YmVnaW4oc3RkOjpkZWNsdmFsPFJhbmdlIGNvbnN0ICY+KCkpKQogICAgPjo6dHlwZSB0eXBlOwp9Owp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gdXNpbmcgcmFuZ2VfZWxlbSA9IHR5cGVuYW1lIHJhbmdlX2VsZW1faTxUPjo6dHlwZTsKCnRlbXBsYXRlIDwKICAgIHR5cGVuYW1lIFJhbmdlLAogICAgdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxoYXNfYmVnaW48UmFuZ2U+Ojp2YWx1ZT46OnR5cGUKPgppbnQgY291bnQoUmFuZ2UgY29uc3QgJiByYW5nZSwgcmFuZ2VfZWxlbTxSYW5nZT4gdmFsdWUpCnsKICAgIGludCBuID0gMDsKICAgIGZvcihhdXRvIGNvbnN0ICYgZSA6IHJhbmdlKSBpZihlPT12YWx1ZSkgKytuOwogICAgcmV0dXJuIG47Cn0KCnN0cnVjdCBTIHt9OwoKaW50IGNvdW50KFMgY29uc3QgJiBzLCBpbnQpIHsgcmV0dXJuIDEwOyB9CgppbnQgbWFpbigpCnsKICAgIGludCBhcnJbXSA9IHsgMSwgMiwgMiwgMyB9OwogICAgc3RkOjpjb3V0IDw8IGNvdW50KGFyciwgMikgPDwgJ1xuJzsKICAgIFMgczsKICAgIHN0ZDo6Y291dCA8PCBjb3VudChzLCAxKSA8PCAnXG4nOwoKICAgIHJldHVybiAwOwp9