1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // <locale>
11 
12 // template <class Facet> locale combine(const locale& other) const;
13 
14 #include <locale>
15 #include <new>
16 #include <cassert>
17 
18 int new_called = 0;
19 
20 void* operator new(std::size_t s) throw(std::bad_alloc)
21 {
22     ++new_called;
23     return std::malloc(s);
24 }
25 
26 void  operator delete(void* p) throw()
27 {
28     --new_called;
29     std::free(p);
30 }
31 
32 void check(const std::locale& loc)
33 {
34     assert(std::has_facet<std::collate<char> >(loc));
35     assert(std::has_facet<std::collate<wchar_t> >(loc));
36 
37     assert(std::has_facet<std::ctype<char> >(loc));
38     assert(std::has_facet<std::ctype<wchar_t> >(loc));
39     assert((std::has_facet<std::codecvt<char, char, std::mbstate_t> >(loc)));
40     assert((std::has_facet<std::codecvt<char16_t, char, std::mbstate_t> >(loc)));
41     assert((std::has_facet<std::codecvt<char32_t, char, std::mbstate_t> >(loc)));
42     assert((std::has_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(loc)));
43 
44     assert((std::has_facet<std::moneypunct<char> >(loc)));
45     assert((std::has_facet<std::moneypunct<wchar_t> >(loc)));
46     assert((std::has_facet<std::money_get<char> >(loc)));
47     assert((std::has_facet<std::money_get<wchar_t> >(loc)));
48     assert((std::has_facet<std::money_put<char> >(loc)));
49     assert((std::has_facet<std::money_put<wchar_t> >(loc)));
50 
51     assert((std::has_facet<std::numpunct<char> >(loc)));
52     assert((std::has_facet<std::numpunct<wchar_t> >(loc)));
53     assert((std::has_facet<std::num_get<char> >(loc)));
54     assert((std::has_facet<std::num_get<wchar_t> >(loc)));
55     assert((std::has_facet<std::num_put<char> >(loc)));
56     assert((std::has_facet<std::num_put<wchar_t> >(loc)));
57 
58     assert((std::has_facet<std::time_get<char> >(loc)));
59     assert((std::has_facet<std::time_get<wchar_t> >(loc)));
60     assert((std::has_facet<std::time_put<char> >(loc)));
61     assert((std::has_facet<std::time_put<wchar_t> >(loc)));
62 
63     assert((std::has_facet<std::messages<char> >(loc)));
64     assert((std::has_facet<std::messages<wchar_t> >(loc)));
65 }
66 
67 struct my_facet
68     : public std::locale::facet
69 {
70     int test() const {return 5;}
71 
72     static std::locale::id id;
73 };
74 
75 std::locale::id my_facet::id;
76 
77 int main()
78 {
79 {
80     {
81         std::locale loc;
82         std::locale loc2(loc, new my_facet);
83         std::locale loc3 = loc.combine<my_facet>(loc2);
84         check(loc3);
85         assert(loc3.name() == "*");
86         assert((std::has_facet<my_facet>(loc3)));
87         const my_facet& f = std::use_facet<my_facet>(loc3);
88         assert(f.test() == 5);
89     }
90     assert(new_called == 0);
91 }
92 {
93     {
94         std::locale loc;
95         std::locale loc2;
96         try
97         {
98             std::locale loc3 = loc.combine<my_facet>(loc2);
99             assert(false);
100         }
101         catch (std::runtime_error&)
102         {
103         }
104     }
105     assert(new_called == 0);
106 }
107 }
108