15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <functional>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // class function<R(ArgTypes...)>
125a83710eSEric Fiselier 
135a83710eSEric Fiselier // R operator()(ArgTypes... args) const
145a83710eSEric Fiselier 
15b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
16*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
17b4fb705eSLouis Dionne 
18434dc0a5SKonstantin Varlamov // Address Sanitizer doesn't instrument weak symbols on Linux. When a key
19434dc0a5SKonstantin Varlamov // function is defined for bad_function_call's vtable, its typeinfo and vtable
20434dc0a5SKonstantin Varlamov // will be defined as strong symbols in the library and weak symbols in other
21434dc0a5SKonstantin Varlamov // translation units. Only the strong symbol will be instrumented, increasing
22434dc0a5SKonstantin Varlamov // its size (due to the redzone) and leading to a serious ODR violation
23434dc0a5SKonstantin Varlamov // resulting in a crash.
24434dc0a5SKonstantin Varlamov // Some relevant bugs:
25434dc0a5SKonstantin Varlamov // https://github.com/google/sanitizers/issues/1017
26434dc0a5SKonstantin Varlamov // https://github.com/google/sanitizers/issues/619
27434dc0a5SKonstantin Varlamov // https://github.com/google/sanitizers/issues/398
28434dc0a5SKonstantin Varlamov // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016
29434dc0a5SKonstantin Varlamov // UNSUPPORTED: asan
30434dc0a5SKonstantin Varlamov 
315a83710eSEric Fiselier #include <functional>
325a83710eSEric Fiselier #include <cassert>
335a83710eSEric Fiselier 
347fc6a556SMarshall Clow #include "test_macros.h"
357fc6a556SMarshall Clow 
3688558e22SEric Fiselier 
375a83710eSEric Fiselier int count = 0;
385a83710eSEric Fiselier 
3988558e22SEric Fiselier 
4088558e22SEric Fiselier // 0 args, return int
4188558e22SEric Fiselier 
f_int_0()4288558e22SEric Fiselier int f_int_0()
4388558e22SEric Fiselier {
4488558e22SEric Fiselier     return 3;
4588558e22SEric Fiselier }
4688558e22SEric Fiselier 
4788558e22SEric Fiselier struct A_int_0
4888558e22SEric Fiselier {
operator ()A_int_04988558e22SEric Fiselier     int operator()() {return 4;}
5088558e22SEric Fiselier };
5188558e22SEric Fiselier 
test_int_0()5288558e22SEric Fiselier void test_int_0()
5388558e22SEric Fiselier {
5488558e22SEric Fiselier     // function
5588558e22SEric Fiselier     {
5688558e22SEric Fiselier         std::function<int ()> r1(f_int_0);
5788558e22SEric Fiselier         assert(r1() == 3);
5888558e22SEric Fiselier     }
5988558e22SEric Fiselier     // function pointer
6088558e22SEric Fiselier     {
6188558e22SEric Fiselier         int (*fp)() = f_int_0;
6288558e22SEric Fiselier         std::function<int ()> r1(fp);
6388558e22SEric Fiselier         assert(r1() == 3);
6488558e22SEric Fiselier     }
6588558e22SEric Fiselier     // functor
6688558e22SEric Fiselier     {
6788558e22SEric Fiselier         A_int_0 a0;
6888558e22SEric Fiselier         std::function<int ()> r1(a0);
6988558e22SEric Fiselier         assert(r1() == 4);
7088558e22SEric Fiselier     }
7188558e22SEric Fiselier }
7288558e22SEric Fiselier 
7388558e22SEric Fiselier 
7488558e22SEric Fiselier // 0 args, return void
7588558e22SEric Fiselier 
f_void_0()7688558e22SEric Fiselier void f_void_0()
7788558e22SEric Fiselier {
7888558e22SEric Fiselier     ++count;
7988558e22SEric Fiselier }
8088558e22SEric Fiselier 
8188558e22SEric Fiselier struct A_void_0
8288558e22SEric Fiselier {
operator ()A_void_08388558e22SEric Fiselier     void operator()() {++count;}
8488558e22SEric Fiselier };
8588558e22SEric Fiselier 
8688558e22SEric Fiselier void
test_void_0()8788558e22SEric Fiselier test_void_0()
8888558e22SEric Fiselier {
8988558e22SEric Fiselier     int save_count = count;
9088558e22SEric Fiselier     // function
9188558e22SEric Fiselier     {
9288558e22SEric Fiselier         std::function<void ()> r1(f_void_0);
9388558e22SEric Fiselier         r1();
9488558e22SEric Fiselier         assert(count == save_count+1);
9588558e22SEric Fiselier         save_count = count;
9688558e22SEric Fiselier     }
9788558e22SEric Fiselier     // function pointer
9888558e22SEric Fiselier     {
9988558e22SEric Fiselier         void (*fp)() = f_void_0;
10088558e22SEric Fiselier         std::function<void ()> r1(fp);
10188558e22SEric Fiselier         r1();
10288558e22SEric Fiselier         assert(count == save_count+1);
10388558e22SEric Fiselier         save_count = count;
10488558e22SEric Fiselier     }
10588558e22SEric Fiselier     // functor
10688558e22SEric Fiselier     {
10788558e22SEric Fiselier         A_void_0 a0;
10888558e22SEric Fiselier         std::function<void ()> r1(a0);
10988558e22SEric Fiselier         r1();
11088558e22SEric Fiselier         assert(count == save_count+1);
11188558e22SEric Fiselier         save_count = count;
11288558e22SEric Fiselier     }
11388558e22SEric Fiselier }
11488558e22SEric Fiselier 
1155a83710eSEric Fiselier // 1 arg, return void
1165a83710eSEric Fiselier 
f_void_1(int i)1175a83710eSEric Fiselier void f_void_1(int i)
1185a83710eSEric Fiselier {
1195a83710eSEric Fiselier     count += i;
1205a83710eSEric Fiselier }
1215a83710eSEric Fiselier 
1225a83710eSEric Fiselier struct A_void_1
1235a83710eSEric Fiselier {
operator ()A_void_11245a83710eSEric Fiselier     void operator()(int i)
1255a83710eSEric Fiselier     {
1265a83710eSEric Fiselier         count += i;
1275a83710eSEric Fiselier     }
1285a83710eSEric Fiselier 
mem1A_void_11295a83710eSEric Fiselier     void mem1() {++count;}
mem2A_void_11305a83710eSEric Fiselier     void mem2() const {++count;}
1315a83710eSEric Fiselier };
1325a83710eSEric Fiselier 
1335a83710eSEric Fiselier void
test_void_1()1345a83710eSEric Fiselier test_void_1()
1355a83710eSEric Fiselier {
1365a83710eSEric Fiselier     int save_count = count;
1375a83710eSEric Fiselier     // function
1385a83710eSEric Fiselier     {
1395a83710eSEric Fiselier         std::function<void (int)> r1(f_void_1);
1405a83710eSEric Fiselier         int i = 2;
1415a83710eSEric Fiselier         r1(i);
1425a83710eSEric Fiselier         assert(count == save_count+2);
1435a83710eSEric Fiselier         save_count = count;
1445a83710eSEric Fiselier     }
1455a83710eSEric Fiselier     // function pointer
1465a83710eSEric Fiselier     {
1475a83710eSEric Fiselier         void (*fp)(int) = f_void_1;
1485a83710eSEric Fiselier         std::function<void (int)> r1(fp);
1495a83710eSEric Fiselier         int i = 3;
1505a83710eSEric Fiselier         r1(i);
1515a83710eSEric Fiselier         assert(count == save_count+3);
1525a83710eSEric Fiselier         save_count = count;
1535a83710eSEric Fiselier     }
1545a83710eSEric Fiselier     // functor
1555a83710eSEric Fiselier     {
1565a83710eSEric Fiselier         A_void_1 a0;
1575a83710eSEric Fiselier         std::function<void (int)> r1(a0);
1585a83710eSEric Fiselier         int i = 4;
1595a83710eSEric Fiselier         r1(i);
1605a83710eSEric Fiselier         assert(count == save_count+4);
1615a83710eSEric Fiselier         save_count = count;
1625a83710eSEric Fiselier     }
1635a83710eSEric Fiselier     // member function pointer
1645a83710eSEric Fiselier     {
1655a83710eSEric Fiselier         void (A_void_1::*fp)() = &A_void_1::mem1;
1665a83710eSEric Fiselier         std::function<void (A_void_1)> r1(fp);
1675a83710eSEric Fiselier         A_void_1 a;
1685a83710eSEric Fiselier         r1(a);
1695a83710eSEric Fiselier         assert(count == save_count+1);
1705a83710eSEric Fiselier         save_count = count;
1715a83710eSEric Fiselier         A_void_1* ap = &a;
1725a83710eSEric Fiselier         std::function<void (A_void_1*)> r2 = fp;
1735a83710eSEric Fiselier         r2(ap);
1745a83710eSEric Fiselier         assert(count == save_count+1);
1755a83710eSEric Fiselier         save_count = count;
1765a83710eSEric Fiselier     }
1775a83710eSEric Fiselier     // const member function pointer
1785a83710eSEric Fiselier     {
1795a83710eSEric Fiselier         void (A_void_1::*fp)() const = &A_void_1::mem2;
1805a83710eSEric Fiselier         std::function<void (A_void_1)> r1(fp);
1815a83710eSEric Fiselier         A_void_1 a;
1825a83710eSEric Fiselier         r1(a);
1835a83710eSEric Fiselier         assert(count == save_count+1);
1845a83710eSEric Fiselier         save_count = count;
1855a83710eSEric Fiselier         std::function<void (A_void_1*)> r2(fp);
1865a83710eSEric Fiselier         A_void_1* ap = &a;
1875a83710eSEric Fiselier         r2(ap);
1885a83710eSEric Fiselier         assert(count == save_count+1);
1895a83710eSEric Fiselier         save_count = count;
1905a83710eSEric Fiselier     }
1915a83710eSEric Fiselier }
1925a83710eSEric Fiselier 
1935a83710eSEric Fiselier // 1 arg, return int
1945a83710eSEric Fiselier 
f_int_1(int i)1955a83710eSEric Fiselier int f_int_1(int i)
1965a83710eSEric Fiselier {
1975a83710eSEric Fiselier     return i + 1;
1985a83710eSEric Fiselier }
1995a83710eSEric Fiselier 
2005a83710eSEric Fiselier struct A_int_1
2015a83710eSEric Fiselier {
A_int_1A_int_12025a83710eSEric Fiselier     A_int_1() : data_(5) {}
operator ()A_int_12035a83710eSEric Fiselier     int operator()(int i)
2045a83710eSEric Fiselier     {
2055a83710eSEric Fiselier         return i - 1;
2065a83710eSEric Fiselier     }
2075a83710eSEric Fiselier 
mem1A_int_12085a83710eSEric Fiselier     int mem1() {return 3;}
mem2A_int_12095a83710eSEric Fiselier     int mem2() const {return 4;}
2105a83710eSEric Fiselier     int data_;
2115a83710eSEric Fiselier };
2125a83710eSEric Fiselier 
2135a83710eSEric Fiselier void
test_int_1()2145a83710eSEric Fiselier test_int_1()
2155a83710eSEric Fiselier {
2165a83710eSEric Fiselier     // function
2175a83710eSEric Fiselier     {
2185a83710eSEric Fiselier         std::function<int (int)> r1(f_int_1);
2195a83710eSEric Fiselier         int i = 2;
2205a83710eSEric Fiselier         assert(r1(i) == 3);
2215a83710eSEric Fiselier     }
2225a83710eSEric Fiselier     // function pointer
2235a83710eSEric Fiselier     {
2245a83710eSEric Fiselier         int (*fp)(int) = f_int_1;
2255a83710eSEric Fiselier         std::function<int (int)> r1(fp);
2265a83710eSEric Fiselier         int i = 3;
2275a83710eSEric Fiselier         assert(r1(i) == 4);
2285a83710eSEric Fiselier     }
2295a83710eSEric Fiselier     // functor
2305a83710eSEric Fiselier     {
2315a83710eSEric Fiselier         A_int_1 a0;
2325a83710eSEric Fiselier         std::function<int (int)> r1(a0);
2335a83710eSEric Fiselier         int i = 4;
2345a83710eSEric Fiselier         assert(r1(i) == 3);
2355a83710eSEric Fiselier     }
2365a83710eSEric Fiselier     // member function pointer
2375a83710eSEric Fiselier     {
2385a83710eSEric Fiselier         int (A_int_1::*fp)() = &A_int_1::mem1;
2395a83710eSEric Fiselier         std::function<int (A_int_1)> r1(fp);
2405a83710eSEric Fiselier         A_int_1 a;
2415a83710eSEric Fiselier         assert(r1(a) == 3);
2425a83710eSEric Fiselier         std::function<int (A_int_1*)> r2(fp);
2435a83710eSEric Fiselier         A_int_1* ap = &a;
2445a83710eSEric Fiselier         assert(r2(ap) == 3);
2455a83710eSEric Fiselier     }
2465a83710eSEric Fiselier     // const member function pointer
2475a83710eSEric Fiselier     {
2485a83710eSEric Fiselier         int (A_int_1::*fp)() const = &A_int_1::mem2;
2495a83710eSEric Fiselier         std::function<int (A_int_1)> r1(fp);
2505a83710eSEric Fiselier         A_int_1 a;
2515a83710eSEric Fiselier         assert(r1(a) == 4);
2525a83710eSEric Fiselier         std::function<int (A_int_1*)> r2(fp);
2535a83710eSEric Fiselier         A_int_1* ap = &a;
2545a83710eSEric Fiselier         assert(r2(ap) == 4);
2555a83710eSEric Fiselier     }
2565a83710eSEric Fiselier     // member data pointer
2575a83710eSEric Fiselier     {
2585a83710eSEric Fiselier         int A_int_1::*fp = &A_int_1::data_;
2595a83710eSEric Fiselier         std::function<int& (A_int_1&)> r1(fp);
2605a83710eSEric Fiselier         A_int_1 a;
2615a83710eSEric Fiselier         assert(r1(a) == 5);
2625a83710eSEric Fiselier         r1(a) = 6;
2635a83710eSEric Fiselier         assert(r1(a) == 6);
2645a83710eSEric Fiselier         std::function<int& (A_int_1*)> r2(fp);
2655a83710eSEric Fiselier         A_int_1* ap = &a;
2665a83710eSEric Fiselier         assert(r2(ap) == 6);
2675a83710eSEric Fiselier         r2(ap) = 7;
2685a83710eSEric Fiselier         assert(r2(ap) == 7);
2695a83710eSEric Fiselier     }
2705a83710eSEric Fiselier }
2715a83710eSEric Fiselier 
2725a83710eSEric Fiselier // 2 arg, return void
2735a83710eSEric Fiselier 
f_void_2(int i,int j)2745a83710eSEric Fiselier void f_void_2(int i, int j)
2755a83710eSEric Fiselier {
2765a83710eSEric Fiselier     count += i+j;
2775a83710eSEric Fiselier }
2785a83710eSEric Fiselier 
2795a83710eSEric Fiselier struct A_void_2
2805a83710eSEric Fiselier {
operator ()A_void_22815a83710eSEric Fiselier     void operator()(int i, int j)
2825a83710eSEric Fiselier     {
2835a83710eSEric Fiselier         count += i+j;
2845a83710eSEric Fiselier     }
2855a83710eSEric Fiselier 
mem1A_void_22865a83710eSEric Fiselier     void mem1(int i) {count += i;}
mem2A_void_22875a83710eSEric Fiselier     void mem2(int i) const {count += i;}
2885a83710eSEric Fiselier };
2895a83710eSEric Fiselier 
2905a83710eSEric Fiselier void
test_void_2()2915a83710eSEric Fiselier test_void_2()
2925a83710eSEric Fiselier {
2935a83710eSEric Fiselier     int save_count = count;
2945a83710eSEric Fiselier     // function
2955a83710eSEric Fiselier     {
2965a83710eSEric Fiselier         std::function<void (int, int)> r1(f_void_2);
2975a83710eSEric Fiselier         int i = 2;
2985a83710eSEric Fiselier         int j = 3;
2995a83710eSEric Fiselier         r1(i, j);
3005a83710eSEric Fiselier         assert(count == save_count+5);
3015a83710eSEric Fiselier         save_count = count;
3025a83710eSEric Fiselier     }
3035a83710eSEric Fiselier     // function pointer
3045a83710eSEric Fiselier     {
3055a83710eSEric Fiselier         void (*fp)(int, int) = f_void_2;
3065a83710eSEric Fiselier         std::function<void (int, int)> r1(fp);
3075a83710eSEric Fiselier         int i = 3;
3085a83710eSEric Fiselier         int j = 4;
3095a83710eSEric Fiselier         r1(i, j);
3105a83710eSEric Fiselier         assert(count == save_count+7);
3115a83710eSEric Fiselier         save_count = count;
3125a83710eSEric Fiselier     }
3135a83710eSEric Fiselier     // functor
3145a83710eSEric Fiselier     {
3155a83710eSEric Fiselier         A_void_2 a0;
3165a83710eSEric Fiselier         std::function<void (int, int)> r1(a0);
3175a83710eSEric Fiselier         int i = 4;
3185a83710eSEric Fiselier         int j = 5;
3195a83710eSEric Fiselier         r1(i, j);
3205a83710eSEric Fiselier         assert(count == save_count+9);
3215a83710eSEric Fiselier         save_count = count;
3225a83710eSEric Fiselier     }
3235a83710eSEric Fiselier     // member function pointer
3245a83710eSEric Fiselier     {
3255a83710eSEric Fiselier         void (A_void_2::*fp)(int) = &A_void_2::mem1;
3265a83710eSEric Fiselier         std::function<void (A_void_2, int)> r1(fp);
3275a83710eSEric Fiselier         A_void_2 a;
3285a83710eSEric Fiselier         int i = 3;
3295a83710eSEric Fiselier         r1(a, i);
3305a83710eSEric Fiselier         assert(count == save_count+3);
3315a83710eSEric Fiselier         save_count = count;
3325a83710eSEric Fiselier         std::function<void (A_void_2*, int)> r2(fp);
3335a83710eSEric Fiselier         A_void_2* ap = &a;
3345a83710eSEric Fiselier         r2(ap, i);
3355a83710eSEric Fiselier         assert(count == save_count+3);
3365a83710eSEric Fiselier         save_count = count;
3375a83710eSEric Fiselier     }
3385a83710eSEric Fiselier     // const member function pointer
3395a83710eSEric Fiselier     {
3405a83710eSEric Fiselier         void (A_void_2::*fp)(int) const = &A_void_2::mem2;
3415a83710eSEric Fiselier         std::function<void (A_void_2, int)> r1(fp);
3425a83710eSEric Fiselier         A_void_2 a;
3435a83710eSEric Fiselier         int i = 4;
3445a83710eSEric Fiselier         r1(a, i);
3455a83710eSEric Fiselier         assert(count == save_count+4);
3465a83710eSEric Fiselier         save_count = count;
3475a83710eSEric Fiselier         std::function<void (A_void_2*, int)> r2(fp);
3485a83710eSEric Fiselier         A_void_2* ap = &a;
3495a83710eSEric Fiselier         r2(ap, i);
3505a83710eSEric Fiselier         assert(count == save_count+4);
3515a83710eSEric Fiselier         save_count = count;
3525a83710eSEric Fiselier     }
3535a83710eSEric Fiselier }
3545a83710eSEric Fiselier 
3555a83710eSEric Fiselier // 2 arg, return int
3565a83710eSEric Fiselier 
f_int_2(int i,int j)3575a83710eSEric Fiselier int f_int_2(int i, int j)
3585a83710eSEric Fiselier {
3595a83710eSEric Fiselier     return i+j;
3605a83710eSEric Fiselier }
3615a83710eSEric Fiselier 
3625a83710eSEric Fiselier struct A_int_2
3635a83710eSEric Fiselier {
operator ()A_int_23645a83710eSEric Fiselier     int operator()(int i, int j)
3655a83710eSEric Fiselier     {
3665a83710eSEric Fiselier         return i+j;
3675a83710eSEric Fiselier     }
3685a83710eSEric Fiselier 
mem1A_int_23695a83710eSEric Fiselier     int mem1(int i) {return i+1;}
mem2A_int_23705a83710eSEric Fiselier     int mem2(int i) const {return i+2;}
3715a83710eSEric Fiselier };
3725a83710eSEric Fiselier 
test_int_2()37388558e22SEric Fiselier void test_int_2()
3745a83710eSEric Fiselier {
3755a83710eSEric Fiselier     // function
3765a83710eSEric Fiselier     {
3775a83710eSEric Fiselier         std::function<int (int, int)> r1(f_int_2);
3785a83710eSEric Fiselier         int i = 2;
3795a83710eSEric Fiselier         int j = 3;
3805a83710eSEric Fiselier         assert(r1(i, j) == i+j);
3815a83710eSEric Fiselier     }
3825a83710eSEric Fiselier     // function pointer
3835a83710eSEric Fiselier     {
3845a83710eSEric Fiselier         int (*fp)(int, int) = f_int_2;
3855a83710eSEric Fiselier         std::function<int (int, int)> r1(fp);
3865a83710eSEric Fiselier         int i = 3;
3875a83710eSEric Fiselier         int j = 4;
3885a83710eSEric Fiselier         assert(r1(i, j) == i+j);
3895a83710eSEric Fiselier     }
3905a83710eSEric Fiselier     // functor
3915a83710eSEric Fiselier     {
3925a83710eSEric Fiselier         A_int_2 a0;
3935a83710eSEric Fiselier         std::function<int (int, int)> r1(a0);
3945a83710eSEric Fiselier         int i = 4;
3955a83710eSEric Fiselier         int j = 5;
3965a83710eSEric Fiselier         assert(r1(i, j) == i+j);
3975a83710eSEric Fiselier     }
3985a83710eSEric Fiselier     // member function pointer
3995a83710eSEric Fiselier     {
4005a83710eSEric Fiselier         int(A_int_2::*fp)(int) = &A_int_2::mem1;
4015a83710eSEric Fiselier         std::function<int (A_int_2, int)> r1(fp);
4025a83710eSEric Fiselier         A_int_2 a;
4035a83710eSEric Fiselier         int i = 3;
4045a83710eSEric Fiselier         assert(r1(a, i) == i+1);
4055a83710eSEric Fiselier         std::function<int (A_int_2*, int)> r2(fp);
4065a83710eSEric Fiselier         A_int_2* ap = &a;
4075a83710eSEric Fiselier         assert(r2(ap, i) == i+1);
4085a83710eSEric Fiselier     }
4095a83710eSEric Fiselier     // const member function pointer
4105a83710eSEric Fiselier     {
4115a83710eSEric Fiselier         int (A_int_2::*fp)(int) const = &A_int_2::mem2;
4125a83710eSEric Fiselier         std::function<int (A_int_2, int)> r1(fp);
4135a83710eSEric Fiselier         A_int_2 a;
4145a83710eSEric Fiselier         int i = 4;
4155a83710eSEric Fiselier         assert(r1(a, i) == i+2);
4165a83710eSEric Fiselier         std::function<int (A_int_2*, int)> r2(fp);
4175a83710eSEric Fiselier         A_int_2* ap = &a;
4185a83710eSEric Fiselier         assert(r2(ap, i) == i+2);
4195a83710eSEric Fiselier     }
4205a83710eSEric Fiselier }
4215a83710eSEric Fiselier 
main(int,char **)4222df59c50SJF Bastien int main(int, char**)
4235a83710eSEric Fiselier {
42488558e22SEric Fiselier     test_void_0();
42588558e22SEric Fiselier     test_int_0();
4265a83710eSEric Fiselier     test_void_1();
4275a83710eSEric Fiselier     test_int_1();
4285a83710eSEric Fiselier     test_void_2();
42988558e22SEric Fiselier     test_int_2();
4302df59c50SJF Bastien 
4312df59c50SJF Bastien   return 0;
4325a83710eSEric Fiselier }
433