1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2008-2012.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // See http://www.boost.org/libs/move for documentation.
9 //
10 //////////////////////////////////////////////////////////////////////////////
11 
12 #include <boost/move/detail/config_begin.hpp>
13 #include <cassert>
14 
15 //[file_descriptor_def
16 
17 #include <boost/move/utility_core.hpp>
18 #include <stdexcept>
19 
20 class file_descriptor
21 {
22    //<-
operating_system_open_file(const char *)23    int operating_system_open_file(const char *)
24    {
25       return 1;
26    }
27 
operating_system_close_file(int fd)28    void operating_system_close_file(int fd)
29    {  (void)fd;   assert(fd != 0); }
30    //->
31    int os_descr_;
32 
33    private:
34    BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)
35 
36    public:
file_descriptor(const char * filename)37    explicit file_descriptor(const char *filename)              //Constructor
38       : os_descr_(operating_system_open_file(filename))
39    {  if(!os_descr_) throw std::runtime_error("file not found");  }
40 
~file_descriptor()41    ~file_descriptor()                                          //Destructor
42    {  if(os_descr_)  operating_system_close_file(os_descr_);  }
43 
file_descriptor(BOOST_RV_REF (file_descriptor)x)44    file_descriptor(BOOST_RV_REF(file_descriptor) x)            // Move ctor
45       :  os_descr_(x.os_descr_)
46    {  x.os_descr_ = 0;  }
47 
operator =(BOOST_RV_REF (file_descriptor)x)48    file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
49    {
50       if(os_descr_) operating_system_close_file(os_descr_);
51       os_descr_   = x.os_descr_;
52       x.os_descr_ = 0;
53       return *this;
54    }
55 
empty() const56    bool empty() const   {  return os_descr_ == 0;  }
57 };
58 
59 //]
60 
61 //[file_descriptor_example
62 #include <boost/container/vector.hpp>
63 #include <cassert>
64 
65 //Remember: 'file_descriptor' is NOT copyable, but it
66 //can be returned from functions thanks to move semantics
create_file_descriptor(const char * filename)67 file_descriptor create_file_descriptor(const char *filename)
68 {  return file_descriptor(filename);  }
69 
main()70 int main()
71 {
72    //Open a file obtaining its descriptor, the temporary
73    //returned from 'create_file_descriptor' is moved to 'fd'.
74    file_descriptor fd = create_file_descriptor("filename");
75    assert(!fd.empty());
76 
77    //Now move fd into a vector
78    boost::container::vector<file_descriptor> v;
79    v.push_back(boost::move(fd));
80 
81    //Check ownership has been transferred
82    assert(fd.empty());
83    assert(!v[0].empty());
84 
85    //Compilation error if uncommented since file_descriptor is not copyable
86    //and vector copy construction requires value_type's copy constructor:
87    //boost::container::vector<file_descriptor> v2(v);
88    return 0;
89 }
90 //]
91 
92 #include <boost/move/detail/config_end.hpp>
93